diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,11 @@
 
 h-raylib's version numbers do not follow the usual format. The first two numbers in the version track the underlying C raylib version. For example, `5.1.x.x` versions use raylib 5.1 under the hood. The third number represents breaking changes (renamed/deleted functions or modules). The last number represents non-breaking changes (new functions or modules, bug fixes, etc). The safest version bound format to use is `h-raylib >=x.y.z.w && <x.y.(z+1)` (instead of the usual `^>=` bound).
 
+## Version 5.5.2.1
+_28 October 2024_
+
+- Bug fixes for web compilation
+
 ## Version 5.5.2.0
 _21 October 2024_
 
diff --git a/default.nix b/default.nix
--- a/default.nix
+++ b/default.nix
@@ -3,7 +3,7 @@
 }:
 mkDerivation {
   pname = "h-raylib";
-  version = "5.5.2.0";
+  version = "5.5.2.1";
   src = ./.;
   isLibrary = true;
   isExecutable = buildExamples;
diff --git a/examples/first-person-camera/src/Main.hs b/examples/first-person-camera/src/Main.hs
--- a/examples/first-person-camera/src/Main.hs
+++ b/examples/first-person-camera/src/Main.hs
@@ -1,44 +1,46 @@
 {-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Main where
 
-import Raylib.Core (clearBackground, disableCursor)
+import Raylib.Core (initWindowUnmanaged, setTargetFPS, windowShouldClose, closeWindow, clearBackground, disableCursor)
 import Raylib.Core.Camera (updateCamera)
 import Raylib.Core.Models (drawCircle3D, drawCubeWiresV, drawLine3D)
 import Raylib.Core.Text (drawFPS)
 import Raylib.Types (Camera3D (Camera3D), CameraMode (CameraModeFirstPerson), CameraProjection (CameraPerspective), pattern Vector3)
-import Raylib.Util (drawing, mode3D, whileWindowOpen_, withWindow)
+import Raylib.Util (drawing, mode3D, raylibApplication)
 import Raylib.Util.Colors (black, white)
 
-main :: IO ()
-main = do
-  withWindow
-    600
-    450
-    "raylib [core] example - first person camera"
-    60
-    ( \_ -> do
-        disableCursor
+startup :: IO Camera3D
+startup = do
+  initWindowUnmanaged 600 450 "raylib [core] example - first person camera"
+  setTargetFPS 60
+  disableCursor
 
-        let camera = Camera3D (Vector3 0 0 0) (Vector3 2 0 1) (Vector3 0 1 0) 70 CameraPerspective
+  return $ Camera3D (Vector3 0 0 0) (Vector3 2 0 1) (Vector3 0 1 0) 70 CameraPerspective
 
-        whileWindowOpen_
-          ( \c ->
-              drawing
-                ( do
-                    clearBackground black
-                    drawFPS 10 20
+mainLoop :: Camera3D -> IO Camera3D
+mainLoop camera =
+  drawing
+    ( do
+        clearBackground black
+        drawFPS 10 20
 
-                    mode3D
-                      c
-                      ( do
-                          drawCircle3D (Vector3 2 0 1) 2 (Vector3 0 0 0) 0 white
-                          drawLine3D (Vector3 3 (-1) 1) (Vector3 1 1 1) white
-                          drawLine3D (Vector3 4 2 2) (Vector3 1 (-1) 1) white
-                          drawCubeWiresV (Vector3 (-2) 0 0) (Vector3 1 1 1) white
-                      )
-                )
-                >> updateCamera c CameraModeFirstPerson
-          )
+        mode3D
           camera
+          ( do
+              drawCircle3D (Vector3 2 0 1) 2 (Vector3 0 0 0) 0 white
+              drawLine3D (Vector3 3 (-1) 1) (Vector3 1 1 1) white
+              drawLine3D (Vector3 4 2 2) (Vector3 1 (-1) 1) white
+              drawCubeWiresV (Vector3 (-2) 0 0) (Vector3 1 1 1) white
+          )
     )
+    >> updateCamera camera CameraModeFirstPerson
+
+shouldClose :: Camera3D -> IO Bool
+shouldClose _ = windowShouldClose
+
+teardown :: Camera3D -> IO ()
+teardown _ = closeWindow Nothing
+
+raylibApplication 'startup 'mainLoop 'shouldClose 'teardown
diff --git a/h-raylib.cabal b/h-raylib.cabal
--- a/h-raylib.cabal
+++ b/h-raylib.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               h-raylib
-version:            5.5.2.0
+version:            5.5.2.1
 synopsis:           Raylib bindings for Haskell
 category:           graphics
 description:
@@ -239,13 +239,13 @@
     Raylib.Internal.Web.Processable
 
   build-depends:
-    , base              >=4.0      && <4.21
+    , base              >=4.0      && <4.22
     , bytestring        >=0.11.0   && <0.13
-    , containers        >=0.6.0    && <0.7.0
-    , exceptions        >=0.10.4   && <0.10.8
-    , lens              >=4.0      && <5.2.4
-    , linear            >=1.22     && <1.23
-    , template-haskell  >=2.16.0.0 && <2.22.0.0
+    , containers        >=0.6.0    && <0.7
+    , exceptions        >=0.10.4   && <0.11
+    , lens              >=4.0      && <5.4
+    , linear            >=1.22     && <1.24
+    , template-haskell  >=2.16.0.0 && <2.23.0.0
     , text              >=2.0      && <2.2
 
   hs-source-dirs:   src
@@ -322,7 +322,6 @@
 
   if flag(platform-web)
     cpp-options: -DWEB_FFI
-    c-sources:   lib/web.c
 
   else
     cc-options:
diff --git a/lib/rl_internal.c b/lib/rl_internal.c
--- a/lib/rl_internal.c
+++ b/lib/rl_internal.c
diff --git a/lib/web.c b/lib/web.c
deleted file mode 100644
--- a/lib/web.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * See web.h
- */
-
-#include "web.h"
-
-// See https://gitlab.haskell.org/ghc/ghc-wasm-meta#custom-imports
-void _jslog(void *buf, uint32_t len) __attribute__((__import_module__("env"), __import_name__("log")));
-void jslog(void *buf, uint32_t len) { _jslog(buf, len); }
-
-void _jsfree(void *ptr) __attribute__((__import_module__("env"), __import_name__("free")));
-void jsfree(void *ptr) { _jsfree(ptr); }
-
-void *_callRaylibFunction(char *name, uint32_t nameLen, void **params, uint32_t *sizeParams, uint8_t *typeParams, uint32_t numParams, uint32_t returnSizeBytes, uint8_t returnType) __attribute__((__import_module__("env"), __import_name__("callRaylibFunction")));
-void *callRaylibFunction(
-  char *name, uint32_t nameLen, void **params, uint32_t *sizeParams, uint8_t *typeParams, uint32_t numParams, uint32_t returnSizeBytes, uint8_t returnType)
-{
-  return _callRaylibFunction(name, nameLen, params, sizeParams, typeParams, numParams, returnSizeBytes, returnType);
-}
