diff --git a/share/fsl/sbin/update_fsl_package b/share/fsl/sbin/update_fsl_package
index b4cb764a1ea82a1e898133d293c505b4823b8c22..b0396bd1aa39f54e04a47897f05d26bdbae50585 100755
--- a/share/fsl/sbin/update_fsl_package
+++ b/share/fsl/sbin/update_fsl_package
@@ -54,6 +54,28 @@ log = logging.getLogger(__name__)
 
 PUBLIC_FSL_CHANNEL   = 'https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/'
 INTERNAL_FSL_CHANNEL = 'https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/internal/'
+EXTERNALLY_HOSTED_PACKAGES = {
+    'fslpy'           : 'conda-forge',
+    'fsleyes-props'   : 'conda-forge',
+    'fsleyes-widgets' : 'conda-forge',
+    'fsleyes'         : 'conda-forge',
+    'fmrib-unpack'    : 'conda-forge',
+    'file-tree'       : 'conda-forge',
+    'file-tree-fsl'   : 'conda-forge',
+    'spec2nii'        : 'conda-forge',
+}
+"""List of packages which are considered to be part of FSL, but which are hosted
+on an external channel (most likely conda-forge). These packages should still be
+considered for updates.
+
+Version information for these packages is only retrieved if they are
+specifically requested by the user, or if the --external option is used.
+This is because downloading and parsing the conda-forge channeldata information
+takes a very long time.
+
+The values in this dictionary can either be a channel name on
+https://anaconda.org, or a fully qualified channel URL.
+"""
 
 
 def conda(cmd : str, capture_output=True, **kwargs) -> str:
@@ -84,6 +106,7 @@ def conda(cmd : str, capture_output=True, **kwargs) -> str:
     return result.stdout
 
 
+@ft.lru_cache
 def identify_platform() -> str:
     """Figures out what platform we are running on. Returns a platform
     identifier string - one of:
@@ -243,17 +266,66 @@ def query_installed_packages() -> Dict[str, Package]:
     pkgs   = {}
 
     # We are only interested in packages
-    # hosted on the FSL conda channels
+    # hosted on the FSL conda channels,
+    # or those listed in the externally
+    # hosted package list.
     for pkg in info:
-        if pkg['base_url'].rstrip() in channels:
+        if pkg['base_url'].rstrip() in channels or \
+           pkg['name']              in EXTERNALLY_HOSTED_PACKAGES:
             pkgs[pkg['name']] = Package(pkg['name'],
                                         pkg['version'],
                                         pkg['channel'],
                                         pkg['platform'])
-
     return pkgs
 
 
+@ft.lru_cache
+def download_external_package_metadata(pkgname     : str,
+                                       channel_url : str,
+                                       development : bool) -> Optional[Package]:
+    """Downloads metadata about one externally hosted package. The returned
+    Package object does not contain platform or dependency information.
+    """
+
+    # if channel_url is a full url, we
+    # download the full channel metdata
+    # and look up the package
+    if any(channel_url.startswith(p) for p in ('https:', 'http:', 'file:')):
+        chandata = download_channel_metadata(channel_url)
+        pkgs     = identify_packages([chandata], [pkgname], development)
+        return pkgs.get(pkgname, [None])[-1]
+
+    # Othrerwise channel_url is the name
+    # of an anaconda.org channel - we
+    # just retrieve information about
+    # the package
+    channel     = channel_url
+    api_url     = f'https://api.anaconda.org/package/{channel}/'
+    channel_url = f'https://anaconda.org/{channel}/'
+
+    try:
+        meta = http_request(f'{api_url}{pkgname}')
+    except Exception:
+        log.debug(f'Package lookup failed [{pkgname} : {channel_url}]')
+        return None
+
+    # Find the latest available
+    # version for this platform
+    thisplat = ('noarch', identify_platform())
+
+    for finfo in meta['files'][::-1]:
+        version  = finfo['version']
+        platform = finfo['attrs']['subdir']
+        isdev    = development or ('dev' not in version)
+
+        if isdev and (platform in thisplat):
+            return Package(pkgname, version, channel_url, platform)
+
+    # No suitable version available
+    else:
+        return None
+
+
 @ft.lru_cache
 def download_channel_metadata(channel_url : str, **kwargs) -> Tuple[Dict, Dict]:
     """Downloads information about packages hosted at the given conda channel.
@@ -276,7 +348,7 @@ def download_channel_metadata(channel_url : str, **kwargs) -> Tuple[Dict, Dict]:
     Keyword arguments are passed through to the http_request function.
     """
 
-    thisplat = identify_platform()
+    thisplat = ('noarch', identify_platform())
 
     # Load channel and platform metadata - the
     # first gives us a list of all packages that
@@ -291,7 +363,7 @@ def download_channel_metadata(channel_url : str, **kwargs) -> Tuple[Dict, Dict]:
     # only consider packages
     # relevant to this platform
     for platform in chandata['subdirs']:
-        if platform in ('noarch', thisplat):
+        if platform in thisplat:
             purl               = f'{channel_url}/{platform}/repodata.json'
             platdata[platform] = http_request(purl)