ORMs on Falix, honestly

Prisma, Sequelize, and Drizzle all work on the Node.js application — but each needs one Falix-specific step to survive the way servers start. Here's the tested truth for all three, and which to pick.

An ORM (Object-Relational Mapper) lets you write database code in JavaScript instead of raw SQL strings — models, types, and query builders instead of SELECT ... WHERE ?. The three popular Node choices are Prisma, Sequelize, and Drizzle, and the honest question isn't "which is best" but "which actually runs on a Falix server without surprises". Every claim below was tested in a container that starts your code exactly the way the Node.js application does. Short version: all three work — but two of them need one extra step you have to know about.

At a glance
You need A server on the Node.js application
Plan Any
Helps to know Connect your app to a database and SQLite in depth

The one thing that trips ORMs up on Falix

The Node.js application runs npm install automatically on every start when a package.json exists — that's it. It does not run a build step, a code generator, or a database migration for you. Most ORM tutorials assume you'll type extra commands (prisma generate, prisma migrate, drizzle-kit push) in a terminal. On Falix there is no terminal for your server. So the rule is simple:

🎯 Good to know: Anything an ORM needs besides npm install has to run from a postinstall script in your package.json (which the automatic install triggers), or from a Git post-deploy command. This is the same build-on-install trick TypeScript uses on Node.

Keep that in mind and every ORM below becomes reliable. Ignore it and Prisma in particular will crash on first run.

Drizzle — the lightest fit (tested working)

Drizzle is a thin, type-safe query builder. Paired with better-sqlite3 it's the cleanest option here: better-sqlite3 ships prebuilt binaries (no compiler), and Drizzle itself is plain JavaScript with no code-generation step needed at runtime. Install drizzle-orm and better-sqlite3 from the Packages page. Your schema is ordinary JS:

// schema.js
const { sqliteTable, integer, text } = require('drizzle-orm/sqlite-core');

const users = sqliteTable('users', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  name: text('name').notNull(),
  score: integer('score').notNull().default(0),
});
module.exports = { users };
// index.js
const Database = require('better-sqlite3');
const { drizzle } = require('drizzle-orm/better-sqlite3');
const { users } = require('./schema');

const sqlite = new Database('app.db');
sqlite.exec(`CREATE TABLE IF NOT EXISTS users (
  id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, score INTEGER NOT NULL DEFAULT 0
)`);

const db = drizzle(sqlite);
db.insert(users).values({ name: 'alice', score: 5 }).run();
console.log(db.select().from(users).all());   // [{ id: 1, name: 'alice', score: 5 }]

Creating tables with a plain CREATE TABLE IF NOT EXISTS on start keeps it self-contained. Drizzle's own migration tool, drizzle-kit, generates SQL migration files — but you run that on your own computer while developing and commit the result; it isn't needed on the server. Verdict: works with zero Falix-specific setup beyond installing the two packages.

Sequelize — mature and fine (tested working)

Sequelize is the long-established ORM. With the sqlite3 package it works on the Node.js application out of the box — sqlite3 installs a prebuilt binary, and Sequelize's sync() creates your tables, so there's no separate codegen or migration step to wire in:

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize({ dialect: 'sqlite', storage: 'app.db', logging: false });

const User = sequelize.define('User', {
  name:  { type: DataTypes.STRING, allowNull: false },
  score: { type: DataTypes.INTEGER, defaultValue: 0 },
});

(async () => {
  await sequelize.sync();                       // creates the table if missing
  await User.create({ name: 'alice', score: 5 });
  console.log(await User.findAll({ raw: true }));
})();

Install sequelize and sqlite3 from the Packages page. For a managed database instead of SQLite, swap the dialect (mysql with mysql2, or postgres with pg) and pass the connection string. Verdict: works; no build step required.

Prisma — powerful, but needs the postinstall step (tested working)

Prisma is the most feature-rich of the three, and the one people most often report "doesn't work" on hosts like this. It does work — the tested flow ran end-to-end — but only if you respect two facts:

  1. Prisma has a code-generation step (prisma generate) that builds the client from your schema. It won't run by itself on Falix.
  2. Prisma downloads a query engine binary (a few tens of MB) the first time it generates. That download happens during install, so your first start is slower.

The recipe that makes both automatic is a postinstall script — the automatic npm install runs it every start:

{
  "scripts": {
    "postinstall": "prisma generate && prisma db push --skip-generate --accept-data-loss"
  },
  "dependencies":    { "@prisma/client": "^5.22.0" },
  "devDependencies": { "prisma": "^5.22.0" }
}

With a normal prisma/schema.prisma (SQLite datasource) in place, pressing Start runs npm installprisma generate builds the client → prisma db push creates the tables → your app runs. Tested result: a real prisma.user.create() followed by findMany() returned the inserted row on a clean server.

⚠️ Heads up: prisma db push on every start is fine for additive schema changes and solo projects. For anything you care about, generate real migrations locally and run prisma migrate deploy as a Git post-deploy command instead — db push can drop columns to match the schema (that's what --accept-data-loss acknowledges).

If you skip the postinstall and just npm install, the app crashes with "@prisma/client did not initialize yet. Please run prisma generate" — that error is the missing step, not a broken host. Verdict: works, provided you wire in prisma generate (and a migration step).

The honest matrix

ORM Status on the Node.js app Falix-specific step Best when
Drizzle + better-sqlite3 ✅ Works, tested None — pure JS + prebuilt binary You want type-safety with the least friction
Sequelize + sqlite3 ✅ Works, tested None — sync() builds tables You like the mature, batteries-included style
Prisma ✅ Works, tested Required: postinstall: prisma generate (+ a migrate/push step); engine download on first install You want Prisma's schema, migrations, and studio and will set it up

All three also drive a managed MySQL/PostgreSQL database — point them at the connection string from the Databases page instead of a SQLite file, keep it in .env, and the model code is unchanged.

💡 Tip: You don't need an ORM. For a bot or a small app, better-sqlite3 with hand-written SQL and ? parameters (see SQLite in depth) is smaller, faster to start, and has nothing to generate. Reach for an ORM when types and migrations start earning their keep — not before.

Verify it works

Start the server and watch the Console. A working ORM prints the row it just inserted ({ name: 'alice', score: 5 } or similar). For Prisma specifically, the install log should show "Generated Prisma Client" and "Your database is now in sync" before your app output — if you don't see those two lines, the postinstall step didn't run.

Troubleshooting

  • @prisma/client did not initialize yet — the postinstall: prisma generate step is missing. Add it to package.json scripts and restart.
  • First start is very slow with Prisma — that's the query-engine download. It's cached in node_modules afterward, so later starts are fast (until a reinstall wipes node_modules, when it downloads once more).
  • Cannot find module 'sqlite3' / better-sqlite3 — the driver isn't installed. Add it from the Packages page and restart.
  • Tables don't exist at runtime — you never ran the create/migrate step. Sequelize needs sync(), Drizzle needs your CREATE TABLE (or a committed migration), Prisma needs db push/migrate deploy.
  • Data gone after a reinstall — SQLite files live in /home/container and are wiped on reinstall. Point the ORM at a managed database for data that must survive.

For everything past getting them running, the official docs own the detail: prisma.io, sequelize.org, and orm.drizzle.team.


Next steps

Was this guide helpful?