Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,9 @@ with support for Node, Python, Go, PHP, and more.
`MISE_PIPX_UVX`) over TOML settings to maintain consistency with existing
patterns in the codebase.

# Mise Setup

If mise is not available in your environment, install it using the instructions at https://mise.jdx.dev/installing-mise.html.

# Workflow

- If mise is not available in your environment, install it using the instructions at https://mise.jdx.dev/installing-mise.html.
- Take a careful look at @mise.toml to understand what commands should be run at different points in the project lifecycle
- Do not worry about docker cache, etc. Never run `docker system prune` or any other similar commands.
- Do not run `go` directly. Instead, inspect @mise.toml and use `mise run <task>` to run various dev lifecycle commands. For instance, you should not run `go vet`, `go fmt`, `go test`, etc directly.
Expand Down Expand Up @@ -69,4 +66,4 @@ There are normal unit tests, snapshot tests, and integration tests. The integrat
# File Conventions

- Markdown files in @docs/src/content/docs/ should be limited to 80 columns
- Do not fix indentation or formatting manually. This is corrected automatically using `mise run check`
- Do not fix indentation or formatting manually. This is corrected automatically using `mise run check`
10 changes: 9 additions & 1 deletion core/providers/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,16 @@ func (p *NodeProvider) Plan(ctx *generate.GenerateContext) error {
Exclude: []string{"node_modules", ".yarn"},
})

miseLayer := miseStep.GetLayer()
if p.usesCorepack() {
miseLayer = plan.NewStepLayer(install.Name(), plan.Filter{
Include: miseStep.GetOutputPaths(),
})
}

ctx.Deploy.AddAptPackages(runtimeAptPackages)
ctx.Deploy.AddInputs([]plan.Layer{
miseStep.GetLayer(),
miseLayer,
nodeModulesLayer,
buildLayer,
})
Expand Down Expand Up @@ -275,6 +282,7 @@ func (p *NodeProvider) InstallNodeDeps(ctx *generate.GenerateContext, install *g
plan.NewExecShellCommand("npm i -g corepack@latest && corepack enable && corepack prepare --activate"),
})
}

install.AddCommands([]plan.Command{
// it's possible for a package.json to exist without any dependencies, in which case node_modules is not generated
// and bun.lockb, etc are not generated either. However, this path is used to compute the cache key, so we ensure
Expand Down
4 changes: 2 additions & 2 deletions core/providers/node/package_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ func (p PackageManager) installDeps(ctx *generate.GenerateContext, install *gene
if !usingCorepack {
// Set PNPM_HOME so pnpm can create a global bin directory for node-gyp
install.AddEnvVars(map[string]string{
"PNPM_HOME": "/pnpm",
"PNPM_HOME": "/opt/pnpm",
})
install.AddPaths([]string{"/pnpm"})
install.AddPaths([]string{"/opt/pnpm"})
install.AddCommand(plan.NewExecCommand("pnpm add -g node-gyp"))
}

Expand Down
3 changes: 3 additions & 0 deletions docs/src/content/docs/languages/node.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ You can include additional files or directories to include by setting the
separated list of patterns to include. Patterns will automatically be prefixed
with `**/` to match nested files and directories.

Railpack supports building native modules and automatically configures `node-gyp`
when using pnpm.

## Static Sites

Railpack can serve a statically built Node project with zero config. You can
Expand Down
25 changes: 25 additions & 0 deletions examples/node-latest-pnpm-native-deps/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const Database = require('better-sqlite3');

console.log('Node version:', process.version);
console.log('Testing better-sqlite3 (native module)...');

// Create an in-memory database
const db = new Database(':memory:');

// Create a simple table
db.exec('CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)');

// Insert some data
const insert = db.prepare('INSERT INTO test (name) VALUES (?)');
insert.run('pnpm');
insert.run('node-gyp');

// Query the data
const rows = db.prepare('SELECT * FROM test').all();

console.log('Database test successful!');
console.log('Rows:', rows);

db.close();

console.log('✓ better-sqlite3 native module working correctly with pnpm');
2 changes: 2 additions & 0 deletions examples/node-latest-pnpm-native-deps/mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tools]
node = "latest"
16 changes: 16 additions & 0 deletions examples/node-latest-pnpm-native-deps/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "node-latest-pnpm-native-deps",
"version": "1.0.0",
"description": "Test pnpm (via corepack) with native dependencies (better-sqlite3)",
"main": "index.js",
"packageManager": "pnpm@10.22.0",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"better-sqlite3": "^11.8.1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Loading
Loading