diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # j
 
+## 0.1.2.0
+
+  * Add `jload` to load profile
+
 ## 0.1.1.0
 
   * Add `libWindows`
diff --git a/j.cabal b/j.cabal
--- a/j.cabal
+++ b/j.cabal
@@ -1,6 +1,6 @@
 cabal-version:   1.18
 name:            j
-version:         0.1.1.0
+version:         0.1.2.0
 license:         BSD3
 license-file:    LICENSE
 copyright:       Copyright: (c) 2020 Vanessa McHale
diff --git a/src/Language/J.hs b/src/Language/J.hs
--- a/src/Language/J.hs
+++ b/src/Language/J.hs
@@ -52,15 +52,35 @@
 --  Since marshaling data between J and Haskell is expensive, it's best to do as
 --  much computation as possible in J.
 --
+--  == Loading Profile
+--
+--  If you would like to use user libraries, you need to use 'jLoad' on the
+--  'JEnv'. As an example:
+--
+--  @
+--  do
+--      jenv <- 'jinit' 'libLinux'
+--      'jLoad' jenv ('linuxProfile' "9.01")
+--      'bsDispatch' 'jenv' "load'tables/csv'"
+--  @
+--
+--  This will load the CSV addon, assuming it is installed.
+--
 --  = FFI
 --
 --  If you want to marshal data yourself, say to use a @Vector@, look at 'JEnv'.
 module Language.J ( -- * Environment
                     JEnv (..)
                   , jinit
+                  , jLoad
+                  , Profile (..)
+                  , linuxProfile
+                  , macProfile
+                  , windowsProfile
 #ifndef mingw32_HOST_OS
                   , libLinux
                   , libMac
+                  , profLinux
 #else
                   , libWindows
 #endif
@@ -130,6 +150,9 @@
 squashVersion :: JVersion -> String
 squashVersion = concatMap show
 
+squashVersionBS :: JVersion -> BS.ByteString
+squashVersionBS = ASCII.pack . squashVersion
+
 #ifndef mingw32_HOST_OS
 -- | Expected 'RawFilePath' to the library on a Linux machine.
 libLinux :: RawFilePath
@@ -137,12 +160,54 @@
 
 -- | Expected 'RawFilePath' to the library on Mac.
 libMac :: JVersion -> RawFilePath
-libMac v = "/Applications/j64-" <> ASCII.pack (squashVersion v) <> "/bin/libj.dylib"
+libMac v = "/Applications/j64-" <> squashVersionBS v <> "/bin/libj.dylib"
 #else
 -- | @since 0.1.1.0
 libWindows :: JVersion -> FilePath
 libWindows v = "C:\\Program Files\\J" <> squashVersion v <> "\\bin\\j.dll"
 #endif
+
+profLinux :: BS.ByteString -> BS.ByteString
+profLinux v = "/etc/j/" <> v <> "/profile.ijs"
+
+binpathLinux :: BS.ByteString
+binpathLinux = "/usr/bin"
+
+dllLinux :: BS.ByteString -> BS.ByteString
+dllLinux v = "libj.so." <> v
+
+-- | @since 0.1.2.0
+linuxProfile :: BS.ByteString -- ^ J version, e.g. @"9.01"@
+             -> Profile
+linuxProfile ver = Profile (profLinux ver) binpathLinux (dllLinux ver)
+
+-- | @since 0.1.2.0
+macProfile :: JVersion
+           -> Profile
+macProfile v =
+    let binPathMac = "/Applications/j64-" <> squashVersionBS v <> "/bin"
+        in Profile (binPathMac <> "/profile.ijs") binPathMac (binPathMac <> "/libj.dylib")
+
+-- | @since 0.1.2.0
+windowsProfile :: JVersion
+               -> Profile
+windowsProfile v =
+    let binPathWindows = "C:\\Program Files\\J" <> squashVersionBS v <> "\\bin"
+        in Profile (binPathWindows <> "\\profile.ijs") binPathWindows (binPathWindows <> "j.dll")
+
+-- | @since 0.1.2.0
+data Profile = Profile { profPath :: BS.ByteString -- ^ @profile.ijs@
+                       , binPath  :: BS.ByteString
+                       , dllName  :: BS.ByteString
+                       }
+
+-- | Load user profile.
+--
+-- @since 0.1.2.0@
+jLoad :: JEnv
+      -> Profile
+      -> IO ()
+jLoad jenv (Profile fp bin dll) = bsDispatch jenv ("(3 : '0!:0 y')<'"<> fp <> "'[BINPATH_z_=:'" <> bin <> "'[LIBFILE_z_=:'" <> dll <> "'[ARGV_z_=:''")
 
 -- | Get a J environment
 --
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -33,8 +33,26 @@
             , testCase "Uses J to perform a complex calculation" (regress jenv)
             , testCase "Writes strings to J values" (stringRoundtrip jenv)
             -- , testCase "Uses J for something Haskell would have a hard time with" (fill jenv)
+            , testCase "Loads a library" (loadNoFail jenv)
             ]
 
+loadNoFail :: JEnv -> Assertion
+loadNoFail jenv = do
+#ifdef linux_HOST_OS
+    jLoad jenv (linuxProfile "9.01")
+#else
+#ifdef darwin_HOST_OS
+    jLoad jenv (macProfile "8.07")
+#else
+#ifdef mingw32_HOST_OS
+    jLoad jenv (macProfile "9.01")
+#endif
+#endif
+#endif
+    bsDispatch jenv "load'tables/csv'"
+    res <- bsOut jenv
+    assertBool "Doesn't fail" $
+        not ("error: " `BS.isInfixOf` res)
 
 fill :: JEnv -> Assertion
 fill jenv = do
