diff --git a/src/RasterDataSources.jl b/src/RasterDataSources.jl
index d60c15f..fff1ec0 100644
--- a/src/RasterDataSources.jl
+++ b/src/RasterDataSources.jl
@@ -16,7 +16,7 @@ import JSON.Parser as JP
 
 export WorldClim, CHELSA, EarthEnv, AWAP, ALWB, SRTM, MODIS
 
-export BioClim, Climate, Weather, Elevation, LandCover, HabitatHeterogeneity
+export BioClim, BioClimPlus, Climate, Weather, Elevation, LandCover, HabitatHeterogeneity
 
 export Future, CMIP5, CMIP6
 
diff --git a/src/chelsa/bioclim.jl b/src/chelsa/bioclim.jl
index 9741b22..6df781c 100644
--- a/src/chelsa/bioclim.jl
+++ b/src/chelsa/bioclim.jl
@@ -1,8 +1,9 @@
 layers(::Type{CHELSA{BioClim}}) = layers(BioClim)
 layerkeys(::Type{CHELSA{BioClim}}, args...) = layerkeys(BioClim, args...)
+layerkeys(::Type{CHELSA{BioClimPlus}}, args...) = layerkeys(BioClimPlus, args...)
 
 """
-    getraster(source::Type{CHELSA{BioClim}}, [layer]) => Union{Tuple,String}
+    getraster(source::Type{CHELSA{BioClim}}, [layer]; version = 2, [patch]) => Union{Tuple,String}
 
 Download [`CHELSA`](@ref) [`BioClim`](@ref) data from [chelsa-climate.org](https://chelsa-climate.org/).
 
@@ -11,23 +12,57 @@ Download [`CHELSA`](@ref) [`BioClim`](@ref) data from [chelsa-climate.org](https
     or `Symbol`s form `$(layerkeys(BioClim))`. Without a `layer` argument, all layers
     will be downloaded, and a `NamedTuple` of paths returned.
 
+# Keyword arguments
+$CHELSA_KEYWORDS
+
 Returns the filepath/s of the downloaded or pre-existing files.
 """
-getraster(T::Type{CHELSA{BioClim}}, layer::Union{Tuple,Int,Symbol}) = _getraster(T, layer)
+getraster(
+    T::Type{CHELSA{BioClim}}, 
+    layer::Union{Tuple,Int,Symbol}; 
+    version::Int = 2, 
+    patch::Int = latest_patch(T, Val(version))) = _getraster(T, layer, Val(version), patch)
 
-_getraster(T::Type{CHELSA{BioClim}}, layers::Tuple) = _map_layers(T, layers)
-_getraster(T::Type{CHELSA{BioClim}}, layer::Symbol) = _getraster(T, bioclim_int(layer))
-function _getraster(T::Type{CHELSA{BioClim}}, layer::Integer)
+_getraster(T::Type{CHELSA{BioClim}}, layers::Tuple, version, patch) = _map_layers(T, layers, version, patch)
+_getraster(T::Type{CHELSA{BioClim}}, layer::Symbol, version, patch) = _getraster(T, bioclim_int(layer), version, patch)
+function _getraster(T::Type{CHELSA{BioClim}}, layer::Integer, version, patch)
     _check_layer(T, layer)
-    path = rasterpath(T, layer)
-    url = rasterurl(T, layer)
+    path = rasterpath(T, layer, version, patch)
+    url = rasterurl(T, layer, version, patch)
     return _maybe_download(url, path)
 end
 
-rastername(::Type{CHELSA{BioClim}}, layer::Integer) = "CHELSA_bio$(layer)_1981-2010_V.2.1.tif"
+rastername(::Type{CHELSA{BioClim}}, layer::Integer, version::Val{2}, patch) = "CHELSA_bio$(layer)_1981-2010_V.2.$patch.tif"
+rastername(::Type{CHELSA{BioClim}}, layer::Integer, version::Val{1}, patch) = "CHELSA_bio10_$(lpad(layer, 2, "0")).tif"
+
+rasterpath(::Type{CHELSA{BioClim}}) = joinpath(rasterpath(CHELSA), "BioClim")
+rasterpath(T::Type{CHELSA{BioClim}}, layer::Integer, version, patch) = joinpath(rasterpath(T), rastername(T, layer, version, patch))
+
+rasterurl(::Type{CHELSA{BioClim}}, v::Val{2}) = joinpath(rasterurl(CHELSA, v), "climatologies/1981-2010/bio/")
+rasterurl(::Type{CHELSA{BioClim}}, v::Val{1}) = joinpath(rasterurl(CHELSA, v), "climatologies/bio/")
+rasterurl(T::Type{CHELSA{BioClim}}, layer::Integer, version, patch) = joinpath(rasterurl(T, version), rastername(T, layer, version, patch))
 
 rasterpath(::Type{CHELSA{BioClim}}) = joinpath(rasterpath(CHELSA), "BioClim")
 rasterpath(T::Type{CHELSA{BioClim}}, layer::Integer) = joinpath(rasterpath(T), rastername(T, layer))
 
-rasterurl(::Type{CHELSA{BioClim}}) = joinpath(rasterurl(CHELSA), "chelsa_V2/GLOBAL/climatologies/1981-2010/bio/")
-rasterurl(T::Type{CHELSA{BioClim}}, layer::Integer) = joinpath(rasterurl(T), rastername(T, layer))
+### Bioclim+
+layers(::Type{CHELSA{BioClimPlus}}) = layers(BioClimPlus)
+
+getraster(
+    T::Type{CHELSA{BioClimPlus}}, 
+    layer::Union{Tuple,Int,Symbol}; 
+    version::Int = 2, 
+    patch::Int = latest_patch(T, Val(version))) = _getraster(T, layer, Val(version), patch)
+
+_getraster(T::Type{CHELSA{BioClimPlus}}, layers::Tuple, version, patch) = _map_layers(T, layers, version, patch)
+function _getraster(T::Type{CHELSA{BioClimPlus}}, layer::Symbol, version::Val{2}, patch)
+    _check_layer(T, layer)
+    path = rasterpath(T, layer, version, patch)
+    url = rasterurl(T, layer, version, patch)
+    return _maybe_download(url, path)
+end
+
+rastername(::Type{CHELSA{BioClimPlus}}, layer::Symbol, version::Val{2}, patch) = "CHELSA_$(layer)_1981-2010_V.2.$patch.tif"
+rasterpath(::Type{CHELSA{BioClimPlus}}) = joinpath(rasterpath(CHELSA), "BioClim")
+rasterpath(T::Type{CHELSA{BioClimPlus}}, layer::Symbol, version, patch) = joinpath(rasterpath(T), rastername(T, layer, version, patch))
+rasterurl(T::Type{CHELSA{BioClimPlus}}, layer::Symbol, version, patch) = joinpath(rasterurl(CHELSA{BioClim}, version), rastername(T, layer, version, patch))
diff --git a/src/chelsa/shared.jl b/src/chelsa/shared.jl
index f288769..a3702b7 100644
--- a/src/chelsa/shared.jl
+++ b/src/chelsa/shared.jl
@@ -10,4 +10,13 @@ and the [`getraster`](@ref) docs for implementation details.
 struct CHELSA{X} <: RasterDataSource end
 
 rasterpath(::Type{CHELSA}) = joinpath(rasterpath(), "CHELSA")
-rasterurl(::Type{CHELSA}) = URI(scheme="https", host="os.zhdk.cloud.switch.ch", path="/envicloud/chelsa/")
+rasterurl(::Type{CHELSA}, ::Val{2}) = URI(scheme="https", host="os.zhdk.cloud.switch.ch", path="/envicloud/chelsa/chelsa_V2/GLOBAL/")
+rasterurl(::Type{CHELSA}, ::Val{1}) = URI(scheme="https", host="os.zhdk.cloud.switch.ch", path="/envicloud/chelsa/chelsa_V1/")
+
+latest_patch(c::Type{<:CHELSA}, ::Val{1}) = 2
+latest_patch(c::Type{<:CHELSA}, ::Val{2}) = 1
+
+CHELSA_KEYWORDS = """
+- `version`: `Integer` indicating the CHELSA version, currently either `1` or `2`.
+- `patch`: `Integer` indicating the CHELSA patch number. Defaults to the latest patch (V1.2 and V2.1)
+"""
\ No newline at end of file
diff --git a/src/types.jl b/src/types.jl
index ecb3470..05fd9b5 100644
--- a/src/types.jl
+++ b/src/types.jl
@@ -65,6 +65,38 @@ bioclim_key(k::Integer) = keys(bioclim_lookup)[k]
 bioclim_int(k::Integer) = k
 bioclim_int(k::Symbol) = bioclim_lookup[bioclim_key(k)]
 
+"""
+    BioClimPlus <: RasterDataSet
+
+Extended BioClim datasets, available from CHELSA. 
+More information on the CHELSA website: https://chelsa-climate.org/exchelsa-extended-bioclim/
+
+Some of these are available as average annual maximum, minimum, mean, and range. 
+Others have a single value, more like the regular BioClim variables.
+
+They do not usually use `month` or `date` keywords, but may use
+`date` in past/future scenarios. 
+
+Currently implemented for CHELSA as `CHELSA{BioClim}` and `CHELSA{Future{BioClim, args..}}`,
+specifying layer names as `Symbol`s.
+
+See the [`getraster`](@ref) docs for implementation details.
+"""
+struct BioClimPlus <: RasterDataSet end
+
+layerkeys(T::Type{BioClimPlus}) = vcat(collect(layerkeys(BioClim)), bioclimplus_layerkeys)
+
+const _bioclimplus_monthly = (:hurs, :clt, :sfcWind, :vpd, :rsds, :pet, :cmi, :swb)
+const _bioclimplus_gdd = (:gdd, :gddlgd, :gdgfgd, :ngd)
+const _bioclimplus_others = (:fcf, :scd, :npp, :gsl, :gst, :gsp)
+const bioclimplus_layerkeys = [
+    vec([Symbol("$(b)_$(m)") for b in _bioclimplus_monthly, m in [:max, :min, :mean, :range]]);
+    vec([Symbol("$(b)_$(d)") for b in _bioclimplus_gdd, d in [0, 5, 10]]);
+    collect(_bioclimplus_others)
+]
+
+layers(::Type{BioClimPlus}) = bioclimplus_layerkeys
+
 """
     Climate <: RasterDataSet