diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for wgpu-raw-hs
 
+## 0.2.0.1 -- 2021-08-24
+
+- Linux support.
+
 ## 0.2.0.0 -- 2021-08-22
 
 - Microsoft Windows support.
diff --git a/src/WGPU/Raw/Dynamic.hs b/src/WGPU/Raw/Dynamic.hs
--- a/src/WGPU/Raw/Dynamic.hs
+++ b/src/WGPU/Raw/Dynamic.hs
@@ -10,6 +10,7 @@
 
 #ifdef WGPUHS_UNIX
 import System.Posix.DynamicLinker (withDL, dlsym)
+import System.Posix.DynamicLinker.Prim (RTLDFlags(RTLD_NOW))
 
 -- | Load WGPU from a dynamic library and run a program using an instance.
 withWGPU ::
@@ -20,7 +21,8 @@
   -- | Completed IO action.
   IO a
 withWGPU dynlibFile action = do
-  withDL dynlibFile [] $ \dl -> loadDynamicInstance (dlsym dl) >>= action
+  withDL
+    dynlibFile [RTLD_NOW] $ \dl -> loadDynamicInstance (dlsym dl) >>= action
 #endif
 
 #ifdef WGPUHS_WINDOWS
diff --git a/src/WGPU/Raw/GLFWSurface.hs b/src/WGPU/Raw/GLFWSurface.hs
--- a/src/WGPU/Raw/GLFWSurface.hs
+++ b/src/WGPU/Raw/GLFWSurface.hs
@@ -67,11 +67,52 @@
 
 #ifdef WGPUHS_TARGET_LINUX
 
+import WGPU.Raw.Generated.Struct.WGPUSurfaceDescriptorFromXlib
+
 createSurface ::
   WGPUHsInstance ->
   GLFW.Window ->
   IO WGPUSurface
-createSurface inst window = error "Linux: not yet implemented."
+createSurface inst glfwWin = do
+  x11Display <- GLFW.getX11Display glfwWin
+  x11Window <- GLFW.getX11Window glfwWin
+
+  alloca $ \ptr_surfaceDescriptor -> do
+    alloca $ \ptr_chainedStruct -> do
+      alloca $ \ptr_surfaceDescriptorFromXlib -> do
+
+        let surfaceDescriptorFromXlib =
+              WGPUSurfaceDescriptorFromXlib
+              { chain =
+                  WGPUChainedStruct
+                  { next = nullPtr,
+                    sType = WGPUSType.SurfaceDescriptorFromXlib
+                  },
+                display = x11Display,
+                window = fromIntegral x11Window
+              }
+        poke
+          ptr_surfaceDescriptorFromXlib
+          surfaceDescriptorFromXlib
+
+        let chainedStruct =
+             WGPUChainedStruct
+               { next = castPtr ptr_surfaceDescriptorFromXlib,
+                 sType = WGPUSType.SurfaceDescriptorFromXlib
+               }
+        poke ptr_chainedStruct chainedStruct
+
+        let surfaceDescriptor =
+              WGPUSurfaceDescriptor
+                { nextInChain = ptr_chainedStruct,
+                  label = nullPtr
+                }
+        poke ptr_surfaceDescriptor surfaceDescriptor
+
+        wgpuInstanceCreateSurface
+          inst
+          (WGPUInstance nullPtr)
+          ptr_surfaceDescriptor
 
 #endif
 
diff --git a/wgpu-raw-hs.cabal b/wgpu-raw-hs.cabal
--- a/wgpu-raw-hs.cabal
+++ b/wgpu-raw-hs.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               wgpu-raw-hs
-version:            0.2.0.0
+version:            0.2.0.1
 synopsis:           WGPU Raw
 description:
   A very low-level WGPU binding.
