diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for extism-pdk
 
+## 1.0.0.0
+
+* Extism 1.0 compatible release
+
 ## 0.2.0.0
 
 * API redesign, add automatic Haskell encoding using `ToMemory` and `FromMemory` classes
diff --git a/examples/CountVowels.hs b/examples/CountVowels.hs
--- a/examples/CountVowels.hs
+++ b/examples/CountVowels.hs
@@ -1,8 +1,16 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
 module CountVowels where
 
 import Extism.PDK
 import Extism.PDK.JSON
 
+data Output = Output
+  { count :: Int
+  }
+  deriving
+    (Data, Typeable)
+
 isVowel c =
   c == 'a'
     || c == 'A'
@@ -21,6 +29,6 @@
   -- Calculate the number of vowels
   let count = length (filter isVowel s)
   -- Return a JSON object {"count": count} back to the host
-  output $ JSONValue $ object ["count" .= count]
+  output $ JSON $ Output count
 
 foreign export ccall "count_vowels" countVowels :: IO ()
diff --git a/examples/HTTPGet.hs b/examples/HTTPGet.hs
--- a/examples/HTTPGet.hs
+++ b/examples/HTTPGet.hs
@@ -8,7 +8,7 @@
 getInput = do
   req <- tryInput
   case req of
-    Right (JSONValue x) -> return x
+    Right (JSON x) -> return x
     Left e -> do
       putStrLn e
       url <- inputString
diff --git a/examples/Hello.hs b/examples/Hello.hs
--- a/examples/Hello.hs
+++ b/examples/Hello.hs
@@ -1,8 +1,10 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
 module Hello where
 
 import Data.Maybe
 import Extism.PDK
-import Foreign.C.Types
+import Extism.PDK.JSON
 
 defaultGreeting = "Hello"
 
diff --git a/extism-pdk.cabal b/extism-pdk.cabal
--- a/extism-pdk.cabal
+++ b/extism-pdk.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               extism-pdk
-version:            0.2.0.0
+version:            1.0.0.0
 
 -- A short (one-line) description of the package.
 synopsis: Extism Plugin Development Kit
@@ -39,13 +39,14 @@
       bytestring >= 0.11.4 && <= 0.12,
       cereal >= 0.5.8 && < 0.6,
       containers >= 0.6.7 && < 0.7,
-      extism-manifest >= 0.3.0 && <= 1.0.0,
+      extism-manifest >= 1.0.0 && < 2.0.0,
       json >= 0.11 && < 0.12,
       messagepack >= 0.5.5 && < 0.6,
       binary >= 0.8.9 && < 0.9.0
 
     hs-source-dirs:   src
     default-language: Haskell2010
+    c-sources: src/extism-pdk.c
 
 executable hello
     scope: private
diff --git a/src/Extism/PDK.hs b/src/Extism/PDK.hs
--- a/src/Extism/PDK.hs
+++ b/src/Extism/PDK.hs
@@ -6,8 +6,8 @@
   ( module Extism.PDK,
     ToBytes (..),
     FromBytes (..),
-    JSONValue (..),
-    MsgPackValue (..),
+    JSON (..),
+    MsgPack (..),
   )
 where
 
@@ -16,7 +16,8 @@
 import Extism.PDK.Memory
 import qualified Extism.PDK.MsgPack (MsgPack, decode, encode)
 import Extism.PDK.Util
-import Text.JSON (JSON, decode, encode, resultToEither)
+import qualified Text.JSON (decode, encode, resultToEither)
+import qualified Text.JSON.Generic
 
 -- | Get plugin input, returning an error message if the encoding is invalid
 tryInput :: (FromBytes a) => IO (Either String a)
@@ -44,15 +45,9 @@
   readInputBytes len
 
 -- | Get input as 'JSON', this is similar to calling `input (JsonValue ...)`
-inputJSON :: (JSON a) => IO (Either String a)
+inputJSON :: (Text.JSON.Generic.Data a) => IO a
 inputJSON = do
-  s <- tryInput :: IO (Either String String)
-  case s of
-    Left e -> return (Left e)
-    Right x ->
-      case resultToEither $ decode x of
-        Left e -> return (Left e)
-        Right y -> return (Right y)
+  Text.JSON.Generic.decodeJSON <$> input
 
 -- | Set plugin output
 output :: (ToBytes a) => a -> IO ()
@@ -61,9 +56,9 @@
   extismSetOutput offs len
 
 -- | Set plugin output to a JSON encoded version of the provided value
-outputJSON :: (JSON a) => a -> IO ()
+outputJSON :: (Text.JSON.Generic.Data a) => a -> IO ()
 outputJSON x =
-  output (encode x)
+  output (Text.JSON.Generic.encodeJSON x)
 
 -- | Get a variable from the Extism runtime
 getVar :: (FromBytes a) => String -> IO (Maybe a)
@@ -115,23 +110,39 @@
   extismSetError $ memoryOffset s
 
 -- | Log level
-data LogLevel = Info | Debug | Warn | Error
+data LogLevel = LogInfo | LogDebug | LogWarn | LogError
 
 -- | Log to configured log file
 log :: LogLevel -> String -> IO ()
-log Info msg = do
+log LogInfo msg = do
   s <- allocString msg
   extismLogInfo (memoryOffset s)
   free s
-log Debug msg = do
+log LogDebug msg = do
   s <- allocString msg
   extismLogDebug (memoryOffset s)
   free s
-log Warn msg = do
+log LogWarn msg = do
   s <- allocString msg
   extismLogWarn (memoryOffset s)
   free s
-log Error msg = do
+log LogError msg = do
   s <- allocString msg
   extismLogError (memoryOffset s)
   free s
+
+-- Log with "error" level
+logError :: String -> IO ()
+logError = Extism.PDK.log LogError
+
+-- Log with "info" level
+logInfo :: String -> IO ()
+logInfo = Extism.PDK.log LogInfo
+
+-- Log with "debug" level
+logDebug :: String -> IO ()
+logDebug = Extism.PDK.log LogDebug
+
+-- Log with "warn" level
+logWarn :: String -> IO ()
+logWarn = Extism.PDK.log LogWarn
diff --git a/src/Extism/PDK/Bindings.hs b/src/Extism/PDK/Bindings.hs
--- a/src/Extism/PDK/Bindings.hs
+++ b/src/Extism/PDK/Bindings.hs
@@ -49,6 +49,8 @@
 
 foreign import ccall "extism_length" extismLength :: MemoryOffset -> IO MemoryLength
 
+foreign import ccall "extism_length_unsafe" extismLengthUnsafe :: MemoryOffset -> IO MemoryLength
+
 foreign import ccall "extism_free" extismFree :: MemoryOffset -> IO ()
 
 foreign import ccall "extism_input_length" extismInputLength :: IO InputLength
diff --git a/src/Extism/PDK/HTTP.hs b/src/Extism/PDK/HTTP.hs
--- a/src/Extism/PDK/HTTP.hs
+++ b/src/Extism/PDK/HTTP.hs
@@ -1,17 +1,26 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
 -- |
 -- Contains bindings to the Extism PDK HTTP interface
 module Extism.PDK.HTTP where
 
 import Data.ByteString as B
 import Data.Word
-import Extism.JSON (JSON, Nullable (..), Result (..), decode)
-import Extism.Manifest (HTTPRequest (..), headers, method, toString, url)
+import Extism.JSON (Nullable (..))
+import qualified Extism.Manifest (HTTPRequest (..))
 import Extism.PDK
 import Extism.PDK.Bindings
 import Extism.PDK.Memory
+import Text.JSON (Result(..), decode, encode, makeObj)
+import qualified Text.JSON.Generic
 
 -- | HTTP Request
-type Request = HTTPRequest
+data Request = Request
+  { url :: String,
+    headers :: [(String, String)],
+    method :: String
+  }
+  deriving (Text.JSON.Generic.Typeable, Text.JSON.Generic.Data)
 
 -- | HTTP Response
 data Response = Response
@@ -22,21 +31,17 @@
 -- | Creates a new 'Request'
 newRequest :: String -> Request
 newRequest url =
-  HTTPRequest
-    { url = url,
-      headers = Null,
-      method = Null
-    }
+  Request url [] "GET"
 
 -- | Update a 'Request' with the provided HTTP request method (GET, POST, PUT, DELETE, ...)
 withMethod :: String -> Request -> Request
 withMethod meth req =
-  req {method = NotNull meth}
+  req {method = meth}
 
 -- | Update a 'Request' with the provided HTTP request headers
 withHeaders :: [(String, String)] -> Request -> Request
 withHeaders h req =
-  req {headers = NotNull h}
+  req {headers = h}
 
 -- | Access the Memory block associated with a 'Response'
 responseMemory :: Response -> Memory
@@ -55,12 +60,15 @@
 responseString (Response _ mem) = loadString mem
 
 -- | Get the 'Response' body as JSON
-responseJSON :: (JSON a) => Response -> IO (Either String a)
+responseJSON :: (Text.JSON.Generic.Data a) => Response -> IO (Either String a)
 responseJSON (Response _ mem) = do
   json <- decode <$> loadString mem
   case json of
-    Ok json -> return $ Right json
-    Extism.JSON.Error msg -> return (Left msg)
+    Ok json ->
+      case Text.JSON.Generic.fromJSON json of
+        Ok x -> return $ Right x
+        Error msg -> return (Left msg)
+    Error msg -> return (Left msg)
 
 -- | Get the 'Response' body and decode it
 response :: (FromBytes a) => Response -> IO (Either String a)
@@ -70,7 +78,13 @@
 sendRequestWithBody :: (ToBytes a) => Request -> a -> IO Response
 sendRequestWithBody req b = do
   body <- alloc b
-  let json = Extism.Manifest.toString req
+  let json =
+        encode
+          Extism.Manifest.HTTPRequest
+            { Extism.Manifest.url = url req,
+              Extism.Manifest.headers = NotNull $ headers req,
+              Extism.Manifest.method = NotNull $ method req
+            }
   j <- allocString json
   res <- extismHTTPRequest (memoryOffset j) (memoryOffset body)
   free j
@@ -85,7 +99,13 @@
 -- | Send HTTP request with an optional request body
 sendRequest :: (ToBytes a) => Request -> Maybe a -> IO Response
 sendRequest req b =
-  let json = Extism.Manifest.toString req
+  let json =
+        encode
+          Extism.Manifest.HTTPRequest
+            { Extism.Manifest.url = url req,
+              Extism.Manifest.headers = NotNull $ headers req,
+              Extism.Manifest.method = NotNull $ method req
+            }
    in let bodyMem = case b of
             Nothing -> return $ Memory 0 0
             Just b -> alloc b
@@ -99,5 +119,5 @@
             if res == 0
               then return (Response (fromIntegral code) (Memory 0 0))
               else do
-                mem <- findMemory res
-                return (Response (fromIntegral code) mem)
+                len <- extismLengthUnsafe res
+                return (Response (fromIntegral code) (Memory res len))
diff --git a/src/Extism/PDK/JSON.hs b/src/Extism/PDK/JSON.hs
--- a/src/Extism/PDK/JSON.hs
+++ b/src/Extism/PDK/JSON.hs
@@ -1,7 +1,9 @@
 module Extism.PDK.JSON
   ( module Extism.PDK.JSON,
     module Extism.JSON,
+    module Text.JSON.Generic,
   )
 where
 
-import Extism.JSON
+import qualified Extism.JSON
+import Text.JSON.Generic
diff --git a/src/Extism/PDK/Memory.hs b/src/Extism/PDK/Memory.hs
--- a/src/Extism/PDK/Memory.hs
+++ b/src/Extism/PDK/Memory.hs
@@ -8,8 +8,8 @@
     MemoryLength,
     FromBytes (..),
     ToBytes (..),
-    JSONValue (..),
-    MsgPackValue (..),
+    JSON (..),
+    MsgPack (..),
     load,
     loadString,
     loadByteString,
@@ -34,7 +34,8 @@
 import Extism.PDK.Bindings
 import qualified Extism.PDK.MsgPack (MsgPack, decode, encode)
 import Extism.PDK.Util
-import Text.JSON (JSON, decode, encode, resultToEither)
+import qualified Text.JSON (JSON, Result (..), decode, encode)
+import qualified Text.JSON.Generic
 
 -- | Represents a block of memory by offset and length
 data Memory = Memory MemoryOffset MemoryLength
@@ -135,10 +136,10 @@
   toBytes :: a -> B.ByteString
 
 -- | A wrapper type for JSON encoded values
-newtype JSONValue a = JSONValue a
+newtype JSON a = JSON a
 
 -- | A wrapper type for MsgPack encoded values
-newtype MsgPackValue a = MsgPackValue a
+newtype MsgPack a = MsgPack a
 
 instance FromBytes B.ByteString where
   fromBytes = Right
@@ -156,20 +157,23 @@
 instance ToBytes String where
   toBytes = toByteString
 
-instance (JSON a) => FromBytes (JSONValue a) where
+instance (Text.JSON.Generic.Data a) => FromBytes (JSON a) where
   fromBytes mem =
     let a = fromBytes mem
      in case a of
           Left e -> Left e
           Right x ->
-            case resultToEither $ decode x of
-              Left e -> Left e
-              Right y -> Right (JSONValue y)
+            case Text.JSON.decode x of
+              Text.JSON.Error e -> Left e
+              Text.JSON.Ok y ->
+                case Text.JSON.Generic.fromJSON y of
+                  Text.JSON.Error e -> Left e
+                  Text.JSON.Ok z -> Right (JSON z)
 
-instance (JSON a) => ToBytes (JSONValue a) where
-  toBytes (JSONValue x) = toBytes (encode x)
+instance (Text.JSON.Generic.Data a) => ToBytes (JSON a) where
+  toBytes (JSON x) = toBytes (Text.JSON.Generic.encodeJSON x)
 
-instance (Extism.PDK.MsgPack.MsgPack a) => FromBytes (MsgPackValue a) where
+instance (Extism.PDK.MsgPack.MsgPack a) => FromBytes (MsgPack a) where
   fromBytes mem =
     let a = fromBytes mem
      in case a of
@@ -177,10 +181,10 @@
           Right x ->
             case Extism.PDK.MsgPack.decode x of
               Left e -> Left e
-              Right y -> Right (MsgPackValue y)
+              Right y -> Right (MsgPack y)
 
-instance (Extism.PDK.MsgPack.MsgPack a) => ToBytes (MsgPackValue a) where
-  toBytes (MsgPackValue x) = toBytes $ Extism.PDK.MsgPack.encode x
+instance (Extism.PDK.MsgPack.MsgPack a) => ToBytes (MsgPack a) where
+  toBytes (MsgPack x) = toBytes $ Extism.PDK.MsgPack.encode x
 
 instance ToBytes Int32 where
   toBytes i = toBytes $ B.toStrict (runPut (putInt32le i))
diff --git a/src/extism-pdk.c b/src/extism-pdk.c
new file mode 100644
--- /dev/null
+++ b/src/extism-pdk.c
@@ -0,0 +1,75 @@
+#include <stdint.h>
+
+#define IMPORT(a, b) __attribute__((import_module(a), import_name(b)))
+
+typedef uint64_t ExtismPointer;
+
+#define DEFINE(name, t, ...)                                                   \
+  IMPORT("extism:host/env", #name) extern t _##name(__VA_ARGS__);
+
+DEFINE(input_length, uint64_t)
+uint64_t extism_input_length() { return _input_length(); }
+
+DEFINE(length, uint64_t, ExtismPointer)
+uint64_t extism_length(ExtismPointer p) { return _length(p); }
+
+DEFINE(length_unsafe, uint64_t, ExtismPointer)
+uint64_t extism_length_unsafe(ExtismPointer p) { return _length_unsafe(p); }
+
+DEFINE(alloc, ExtismPointer, uint64_t)
+uint64_t extism_alloc(uint64_t n) { return _alloc(n); }
+
+DEFINE(free, void, ExtismPointer)
+void extism_free(uint64_t n) { return _free(n); }
+
+DEFINE(input_load_u8, uint8_t, ExtismPointer)
+uint8_t extism_input_load_u8(ExtismPointer p) { return _input_load_u8(p); }
+
+DEFINE(input_load_u64, uint64_t, ExtismPointer)
+uint64_t extism_input_load_u64(ExtismPointer p) { return _input_load_u64(p); }
+
+DEFINE(output_set, void, ExtismPointer, uint64_t)
+void extism_output_set(ExtismPointer p, uint64_t n) {
+  return _output_set(p, n);
+}
+
+DEFINE(error_set, void, ExtismPointer)
+void extism_error_set(ExtismPointer p) { _error_set(p); }
+
+DEFINE(config_get, ExtismPointer, ExtismPointer)
+ExtismPointer extism_config_get(ExtismPointer p) { return _config_get(p); }
+
+DEFINE(var_get, ExtismPointer, ExtismPointer)
+ExtismPointer extism_var_get(ExtismPointer p) { return _var_get(p); }
+
+DEFINE(var_set, void, ExtismPointer, ExtismPointer)
+void extism_var_set(ExtismPointer k, ExtismPointer v) { return _var_set(k, v); }
+
+DEFINE(store_u8, void, ExtismPointer, uint8_t)
+void extism_store_u8(ExtismPointer p, uint8_t x) { return _store_u8(p, x); }
+
+DEFINE(load_u8, uint8_t, ExtismPointer)
+uint8_t extism_load_u8(ExtismPointer p) { return _load_u8(p); }
+
+DEFINE(store_u64, void, ExtismPointer, uint64_t)
+void extism_store_u64(ExtismPointer p, uint64_t x) { return _store_u64(p, x); }
+
+DEFINE(load_u64, uint64_t, ExtismPointer)
+uint64_t extism_load_u64(ExtismPointer p) { return _load_u64(p); }
+
+DEFINE(http_request, ExtismPointer, ExtismPointer, ExtismPointer)
+ExtismPointer extism_http_request(ExtismPointer req, ExtismPointer body) {
+  return _http_request(req, body);
+}
+
+DEFINE(http_status_code, int32_t)
+int32_t extism_http_status_code() { return _http_status_code(); }
+
+DEFINE(log_info, void, ExtismPointer)
+void extism_log_info(ExtismPointer p) { return _log_info(p); }
+DEFINE(log_debug, void, ExtismPointer)
+void extism_log_debug(ExtismPointer p) { return _log_debug(p); }
+DEFINE(log_warn, void, ExtismPointer)
+void extism_warn_info(ExtismPointer p) { return _log_warn(p); }
+DEFINE(log_error, void, ExtismPointer)
+void extism_log_error(ExtismPointer p) { return _log_error(p); }
