diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Revision history for wgpu-hs
 
+## 0.2.0.0 -- 2021-08-22
+
+- Added MS Windows support for surfaces and DLL loading.
+- Added `withPlatformInstance`: select dynamic library name based on platform.
+
 ## 0.1.0.0 -- 2021-08-20
 
 - Initial (incomplete) API bindings started.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2021 Jonathan Merritt.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+   may be used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/examples/triangle/Main.hs b/examples/triangle/Main.hs
--- a/examples/triangle/Main.hs
+++ b/examples/triangle/Main.hs
@@ -40,7 +40,7 @@
         TextIO.putStrLn "Failed to create GLFW window"
         exitFailure
 
-  WGPU.withInstance "libwgpu_native.dylib" (Just WGPU.logStdout) $ \inst -> do
+  WGPU.withPlatformInstance (Just WGPU.logStdout) $ \inst -> do
     -- set the logging level
     WGPU.setLogLevel inst WGPU.Warn
 
diff --git a/src-internal/WGPU/Internal/ChainedStruct.hs b/src-internal/WGPU/Internal/ChainedStruct.hs
--- a/src-internal/WGPU/Internal/ChainedStruct.hs
+++ b/src-internal/WGPU/Internal/ChainedStruct.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE RecordWildCards #-}
 
--- |
 module WGPU.Internal.ChainedStruct
   ( -- * Types
     ChainedStruct (..),
diff --git a/src-internal/WGPU/Internal/Instance.hs b/src-internal/WGPU/Internal/Instance.hs
--- a/src-internal/WGPU/Internal/Instance.hs
+++ b/src-internal/WGPU/Internal/Instance.hs
@@ -13,6 +13,7 @@
     --
     -- $instance
     Instance (..),
+    withPlatformInstance,
     withInstance,
 
     -- * Logging
@@ -36,6 +37,7 @@
 import Data.Word (Word32, Word8)
 import Foreign (Ptr, freeHaskellFunPtr, nullFunPtr)
 import Foreign.C (CChar, peekCString)
+import qualified System.Info
 import WGPU.Internal.Memory (ToRaw, raw)
 import WGPU.Raw.Dynamic (withWGPU)
 import WGPU.Raw.Generated.Enum.WGPULogLevel (WGPULogLevel (WGPULogLevel))
@@ -78,17 +80,23 @@
 
 -------------------------------------------------------------------------------
 
--- | Logging level.
-data LogLevel
-  = Trace
-  | Debug
-  | Info
-  | Warn
-  | Error
-  deriving (Eq, Show)
-
--- | Logging callback function.
-type LogCallback = LogLevel -> Text -> IO ()
+-- | Load the WGPU API from a dynamic library and supply an 'Instance' to a
+-- program.
+--
+-- This is the same as 'withInstance', except that it uses a default,
+-- per-platform name for the library, based on the value returned by
+-- 'System.Info.os'.
+withPlatformInstance ::
+  -- | Optional logging callback. @'Just' 'logStdout'@ can be supplied here to
+  --   print log messages to @stdout@ for debugging purposes.
+  Maybe LogCallback ->
+  -- | The Program. A function which takes an 'Instance' and returns an IO
+  --   action that uses the instance.
+  (Instance -> IO a) ->
+  -- | IO action which loads the WGPU 'Instance', passes it to the program, and
+  --   returns the result of running the program.
+  IO a
+withPlatformInstance = withInstance platformDylibName
 
 -- | Load the WGPU API from a dynamic library and supply an 'Instance' to a
 -- program.
@@ -124,6 +132,33 @@
           freeHaskellFunPtr logCallback_c
 
       pure result
+
+-- | Return the dynamic library name for a given platform.
+--
+-- This is the dynamic library name that should be passed to the 'withInstance'
+-- function to load the dynamic library.
+platformDylibName :: FilePath
+platformDylibName =
+  case System.Info.os of
+    "darwin" -> "libwgpu_native.dylib"
+    "mingw32" -> "wgpu_native.dll"
+    "linux" -> "libwgpu_native.dylib"
+    other ->
+      error $ "platformDylibName: unknown / unhandled platform: " <> other
+
+-------------------------------------------------------------------------------
+
+-- | Logging level.
+data LogLevel
+  = Trace
+  | Debug
+  | Info
+  | Warn
+  | Error
+  deriving (Eq, Show)
+
+-- | Logging callback function.
+type LogCallback = LogLevel -> Text -> IO ()
 
 -- | Set the current logging level for the instance.
 setLogLevel :: Instance -> LogLevel -> IO ()
diff --git a/src/WGPU.hs b/src/WGPU.hs
--- a/src/WGPU.hs
+++ b/src/WGPU.hs
@@ -16,6 +16,7 @@
     -- * Initialization #initialization#
     -- $initialization
     Instance,
+    withPlatformInstance,
     withInstance,
 
     -- * Surface #surface#
@@ -211,23 +212,13 @@
 --
 -- === Platform Support
 --
--- Currently, only macOS (with the Metal backend) is supported. The limitation
--- is not fundamental and only exists because, so far, only macOS surface
--- creation has been implemented. In the future, other backends should be added.
+-- Currently, macOS (Metal) and Windows are supported. Linux support is planned.
 --
 -- === Dependence on GLFW-b
 --
 -- This package currently uses only
 -- <https://hackage.haskell.org/package/GLFW-b GLFW-b>
--- for windowing and event processing. Clearly, it is undesirable to be
--- tied to only a single library for this purpose, when options like
--- <https://hackage.haskell.org/package/sdl2 sdl2> are available and might be
--- preferred by many users.
---
--- GFLW is used because it is the windowing library used in the C examples from
--- @wgpu-native@ and it exposes an API to obtain a pointer to the underlying
--- windowing system's native window. In the future, other options will be
--- investigated as time permits.
+-- for windowing and event processing.
 --
 -- === Structure of Bindings
 --
@@ -235,55 +226,30 @@
 --
 --   1. The @wgpu-raw-hs-codegen@ package is a code generator for the raw
 --      bindings. It creates all the packages named @WGPU.Raw.Generated.*@
---      (without exception!), using a custom code generator based on
---      `langage-c`. This package is not in Hackage, since it is only used
---      offline.
+--      (without exception!).
 --
 --   2. The <https://hackage.haskell.org/package/wgpu-raw-hs wgpu-raw-hs>
---      package provides raw bindings to @wgpu-native@. These raw bindings are
---      mostly auto-generated, but have some manual curation of top-level types
---      and function aliases. They are "raw" in the sense that they contain raw
---      pointers and are not usable without manual management of memory to
---      construct all the C structs that must be passed to the API.
+--      package provides raw bindings to @wgpu-native@. They are "raw" in the
+--      sense that they contain raw pointers and are not usable without manual
+--      construction of the C structs that must be passed to the API.
 --
 --   3. The @wgpu-hs@ package (this one) provides high-level bindings. These
 --      bindings are written manually. They are improvements on the raw
 --      bindings in the following ways:
 --
---       - There are no more raw @Ptr@ types. Memory for structs passed to the
---         raw API is managed using a type class (@ToRaw@) that encapsulates a
---         mapping between high-level API types and raw types. The possibility
---         to allocate memory as part of this conversion (and later free it) is
---         achieved by embedding conversion to the raw types inside the @ContT@
---         continuation monad.
+--       - There are no more raw @Ptr@ types.
 --
---       - There are no callbacks. Several WebGPU native calls use callbacks to
---         indicate completion rather than blocking. The author decided that, in
---         the Haskell context, blocking was probably preferable. So,
---         internally, these calls are converted into a blocking form by waiting
---         on @MVar@s that are set by the callbacks.
+--       - There are no callbacks.
 --
 --       - Several parts of the API are tweaked slightly to more closely
---         resemble the Rust API. This is done in cases where, for example, a
---         parameter to the C API is unused except in one branch of a sum type.
---         When this can be done easily enough, it is preferred to using the
---         flattened "union" approach.
+--         resemble the Rust API.
 --
---       - Names are de-duplicated. Where possible, names are identical to the C
---         API (sometimes with prefixes removed). However, where name conflicts
---         exist, names are changed to somewhat-idiomatic Haskell variants.
+--       - Names are de-duplicated.
 --
 -- === Native Library Handling
 --
 -- The native library for @wgpu-native@ is not required at compile-time for this
--- package. Indeed, other packages containing executables that depend on this
--- one can be compiled without the native library! Instead, the library is
--- loaded dynamically and its symbols bound at runtime. This has the benefit
--- that the Haskell tooling need not be concerned with handling a Rust library
--- (yay!), but it is a point of common failure at runtime. To achieve this
--- independence, the header files for @wgpu-native@ are packaged inside
--- @wgpu-raw-hs@. Of course, care should be taken to ensure that a
--- fully-compatible version of the library is used at runtime.
+-- package. The library is loaded dynamically at runtime.
 
 -------------------------------------------------------------------------------
 
@@ -296,10 +262,10 @@
 -- <https://github.com/gfx-rs/wgpu-native wgpu-native> is supported.
 --
 -- To load the dynamic library and obtain an instance, use the
--- 'withInstance' bracketing function:
+-- 'withPlatformInstance' or 'withInstance' bracketing functions:
 --
 -- @
--- 'withInstance' "libwgpu_native.dylib" (Just 'logStdout') $ \inst -> do
+-- 'withPlatformInstance' (Just 'logStdout') $ \inst -> do
 --   -- set the logging level (optional)
 --   'setLogLevel' inst 'Warn'
 --   -- run the rest of the program...
diff --git a/wgpu-hs.cabal b/wgpu-hs.cabal
--- a/wgpu-hs.cabal
+++ b/wgpu-hs.cabal
@@ -1,10 +1,11 @@
 cabal-version:      3.0
 name:               wgpu-hs
-version:            0.1.0.0
+version:            0.2.0.0
 synopsis:           WGPU
 description:        A high-level binding to WGPU.
 bug-reports:        https://github.com/lancelet/wgpu-hs/issues
 license:            BSD-3-Clause
+license-file:       LICENSE
 author:             Jonathan Merritt
 maintainer:         j.s.merritt@gmail.com
 copyright:          Copyright (C) Jonathan Merritt, 2021
@@ -69,7 +70,7 @@
     , transformers      ^>=0.5.6
     , vector            ^>=0.12.3
     , wgpu-hs-internal
-    , wgpu-raw-hs       ==0.1.0.3
+    , wgpu-raw-hs       ==0.2.0.0
 
   exposed-modules: WGPU
 
