Skip to content

Conversation

@i-am-the-slime
Copy link
Contributor

@i-am-the-slime i-am-the-slime commented Jan 4, 2026

Replace better-sqlite3 with Node.js native node:sqlite module.

  • Requires Node.js >= 22.5.0 (see release schedule)
  • Named parameter syntax changed slightly (@param with object argument)
  • Suppresses ExperimentalWarning in CLI and tests

@wclr
Copy link
Contributor

wclr commented Jan 5, 2026

Maybe it is better to move to nodejs build-in sql support https://nodejs.org/api/sqlite.html (available from Node 22)

Spago next is a new tool and still not widely used so I don't think that there need to worry about old node version and ignore node platform development.

@i-am-the-slime
Copy link
Contributor Author

@wclr sure, let's get some buy-in first from the maintainers and then we can also go that route.

Main motivation is to avoid having to rebuild spago for different node versions.

@i-am-the-slime i-am-the-slime changed the title Use turso instead of better-sqlite to avoid gyp dependency Use Node.js native sqlite instead of better-sqlite3 Jan 12, 2026
bin/index.dev.js Outdated
@@ -1,4 +1,4 @@
#!/usr/bin/env node
#!/usr/bin/env -S node --no-warnings
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing all the warnings is a terrible idea for a set of reasons 😄

Let's just exclude the warnings for experimental modules: --no-warnings=ExperimentalWarning

FS.mkdirp Paths.globalCachePath
logDebug $ "Global cache: " <> Path.quote Paths.globalCachePath

-- Make sure we have git and purs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node will fail with a horrible error if it doesn't find the module, so I think we should catch it at the startup and error out then.

Implementation sketch:

import Data.Int as Int
import Data.String as String
import Effect.Console as Console
import Node.Process as Process

-- first thing inside main:
main = do
  -- Check that we're running on Node.js >= 22.5.0 (required for node:sqlite)
  let
    -- version is like "v22.5.0" or "22.5.0"
    versionStr = String.stripPrefix (String.Pattern "v") Process.version
      # fromMaybe Process.version
    parts = String.split (String.Pattern ".") versionStr

  case Array.take 2 parts >>= traverse Int.fromString of
    Just [major, minor]
      | major > 22 -> pure unit
      | major == 22 && minor >= 5 -> pure unit
      | otherwise -> do
        Console.error $ "Error: spago requires Node.js v22.5.0 or later (found " <> Process.version <> ")"
        Process.exit' 1
    _ -> do
      -- couldn't parse, issue a warning and let it crash later
      ..

together with this we should also add the engines field to the package.json. Node won't enforce it on install, but will complain about it:

 {                                                                                                      
    "engines": {                                                                                         
      "node": ">=22.5.0"                                                                                 
    }                                                                                                    
  }  

src/Spago/Db.js Outdated
fs.mkdirSync(dir, { recursive: true });
}
} catch (err) {
// ignore - will fail later if needed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we ignoring the error here?

src/Spago/Db.js Outdated
Comment on lines 78 to 79
.prepare("SELECT * FROM package_sets WHERE compiler = ? ORDER BY date DESC LIMIT 1")
.get(compiler);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use positional arguments in a few places, we should use them everywhere, e.g.:

Suggested change
.prepare("SELECT * FROM package_sets WHERE compiler = ? ORDER BY date DESC LIMIT 1")
.get(compiler);
.prepare("SELECT * FROM package_sets WHERE compiler = @compiler ORDER BY date DESC LIMIT 1")
.get({ compiler });

src/Spago/Db.js Outdated
.all();
return row;
}
return Promise.resolve().then(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing code is in Effect, and this database code is sync as well, why turn everything into Promises?

@i-am-the-slime i-am-the-slime marked this pull request as draft January 23, 2026 09:28
@i-am-the-slime i-am-the-slime force-pushed the turso-libsql branch 12 times, most recently from 4bc08d1 to 73f07cc Compare January 24, 2026 12:28
- Use Node.js native node:sqlite module (available from Node 22.5.0)
- Add Node.js version check at startup
- Add engines field to package.json
- Use named parameters consistently in SQL queries
- Suppress ExperimentalWarning for node:sqlite in shebang and CI

Benefits:
- Zero native compilation dependencies (no node-gyp)
- Built-in Node.js module - will stabilize over time
- Same performance - local file-based SQLite database
🐰 Generated with Crush

Assisted-by: Claude Opus 4.5 via Crush <crush@charm.land>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants