Sails.js: a realtime MVC framework for Node.js teams that want Rails-style conventions
Realtime MVC Framework for Node.js
At a glance
- What is it?
- Sails.js pairs an Express-based router with Socket.io and the Waterline ORM. It suits teams building data-oriented APIs and chat-style features, and the last push to the repository was on 2026-05-27.
- Who is it for?
- Adopt Sails.js when you want an Express-compatible Node.js API layer with WebSocket support and a single ORM abstraction across MySQL, PostgreSQL, MongoDB, Redis or local disk, and when the built-in conventions save you from assembling a router, session handling and socket wiring yourself.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 125 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap Sails.js fills between a bare Express app and a full MVC stack
Express gives you a router and middleware. It does not give you a data model layer, a session strategy, a policy system or a WebSocket channel that mirrors your REST endpoints. Sails.js is positioned as a web framework that makes it easy to build custom, enterprise-grade Node.js apps, and the README says it is designed to resemble the MVC architecture from frameworks like Ruby on Rails, but with support for the more modern, data-oriented style of web app and API development. The project describes itself as especially good for building realtime features like chat.
The audience is therefore a Node.js team that has already decided on JavaScript end to end and does not want to hand-assemble the pieces above. If you are writing a small HTTP service with two endpoints and no persistence, Sails.js is more framework than the problem needs. The value shows up when the same resource has to be reachable over HTTP and over a socket, and when the model layer has to survive a change of database without a rewrite of the controllers. That is the specific problem: one set of actions, two transports, one model definition.
How Sails.js wires Express, Socket.io and Waterline together
Sails.js is built on Node.js, Express and Socket.io, according to the compatibility section of the README. The routing layer is Express underneath, but the project ships its own router package, @sailshq/router, as a dependency, so route configuration is Sails-flavoured rather than raw Express. Actions are compatible with Connect middleware, and the README states that in most cases you can paste code into Sails from an existing Express project and everything will work, with the addition that you can use WebSockets to talk to your API and vice versa. That last clause is the architectural claim worth understanding: the same action can be invoked over HTTP or over a socket, which is why the framework can serve a chat feature without a parallel implementation.
The ORM is Waterline, a separate repository under the same organisation. The README describes it as having a well-defined adapter system for supporting all kinds of datastores, with official support for MySQL, PostgreSQL, MongoDB, Redis and local disk or memory. Everything above the adapter is written against Waterline's model API, so the datastore is a configuration choice rather than a code-level one. That is the data flow: request arrives through the router, hits a policy, reaches an action, the action calls a Waterline model, and the adapter translates the query for the specific database.
Since version 1.0, the README notes, Sails supports await out of the box, replacing nested callbacks and their error handling. The README gives this example:
var orgs = await Organization.find();That is a genuine simplification over the callback style the framework used earlier, and it means modern Sails code reads like most other async JavaScript.
Installing Sails.js and lifting a first project
The README gives a two-step install. First install Node.js, then install the Sails CLI globally from npm:
npm install sails -gThe package.json declares a bin entry mapping the sails command to ./bin/sails.js, so after a global install the CLI is on your path. The engines field in the same file lists node >= 0.10.0 and npm >= 1.4.0, which are very old floors; treat them as the minimum the package declares rather than a recommendation.
With the CLI available, scaffold an application. The README shows the command and the generated directory name:
sails new my-appThis creates a project folder with the conventional layout. The repository's own top-level entries give a sense of what a Sails project looks like, since the framework repository itself carries app/, bin/, lib/, errors/, docs/ and test/ directories. Then move into the folder and start the server:
cd my-app
sails liftThe README calls this firing up the server. After a successful lift you should see the framework log its startup and the port it is listening on, and the app is reachable in a browser. The README points to sailsjs.com/get-started for the most up-to-date introduction, which is where the tutorial continues beyond this point. If you are coming from an earlier major version, the README directs you to the upgrading guides on the Sails website, which it says cover all major releases since 2013.
Where Sails.js stops being the right tool
The adapter list is the first boundary. Officially supported databases are MySQL, PostgreSQL, MongoDB, Redis and local disk or memory. Everything else named in the README, including CouchDB, neDB, SQLite, Oracle, MSSQL, DB2, ElasticSearch, Riak, neo4j, OrientDB, Amazon RDS, DynamoDB, Azure Tables, RethinkDB and Solr, is a community adapter. A community adapter is somebody else's repository, and the README does not promise anything about its release cadence or compatibility with the Sails version you install. If your organisation runs Oracle or MSSQL, that is the risk you are accepting, and it is not a small one for a system you intend to keep for years.
The second boundary is release cadence. The repository's recent releases list v1.5.11 from 2024-05-24, v1.5.9 from 2024-04-09 and v1.5.7 from 2023-07-21, while package.json on the default branch declares version 1.5.18. There is a gap between the published release and the version in the repository, and the changelog is the place to look for what is in between. The last push to the repository was on 2026-05-27, which is recent enough that the project is not abandoned, but a team that expects frequent minor releases with new features should check the CHANGELOG.md before assuming a fast cadence.
Third, the framework is opinionated about structure. If your architecture deliberately avoids models, policies and conventional directory layouts, you will spend effort fighting the conventions rather than using them. A plain Express server with a query builder is a better fit for that case, and the README itself frames Sails as compatible with Express rather than a replacement for teams that want Express alone.
Sails.js against NestJS and plain Express for a realtime API
The honest comparison is against two things: Express by itself, and a TypeScript-first framework such as NestJS.
Against plain Express, the difference is what comes in the box. Express gives you routing and middleware; you add a session store, a WebSocket server, an ORM and a policy layer yourself. Sails.js ships express, express-session, @sailshq/csurf for CSRF protection, serve-static, compression and Socket.io as dependencies and wires them into a conventional project structure. The README's claim that you can paste Express code into Sails and have it work is the compatibility bridge; the trade is that you inherit Sails' conventions and its dependency versions rather than choosing your own.
Against NestJS, the difference is the type system and the ORM story. NestJS is built around TypeScript decorators and dependency injection, and typically pairs with TypeORM or Prisma. Sails.js is plain JavaScript in the README's examples, uses Waterline as its ORM, and treats the adapter as the database abstraction boundary. If your team wants compile-time type checking across controllers and models, Sails.js is the weaker choice. If your team wants a Rails-like convention set in JavaScript with a single ORM API across several databases, and realtime support that does not require a second code path, Sails.js is the more direct fit. The two frameworks are not interchangeable; they optimise for different things.
Maintenance cost, upgrade path and the MIT licence
The repository is not archived, and the last push was on 2026-05-27. The published releases, however, are older: v1.5.11 on 2024-05-24, v1.5.9 on 2024-04-09 and v1.5.7 on 2023-07-21. The version in package.json on the default branch is 1.5.18, so the repository carries more than the newest listed release. Anyone pinning a dependency should check npm for the actual published version rather than assuming the repository state matches the registry.
Upgrades are documented rather than implicit. The README states that upgrade guides for all major releases since 2013 are available on the Sails website under Upgrading. That is a better situation than many Node.js projects, where a major version bump arrives with a changelog and nothing else. The cost is that the guides are on the website, not in the repository, so an offline or air-gapped environment has to fetch them separately.
The dependency tree is worth reading before you commit. package.json pins express at 4.22.2, ejs at 3.1.10, async at 2.6.4 and semver at 7.5.2, among others, and carries framework-specific packages such as machine, machine-as-action, parley, flaverr, whelk, skipper and @sailshq/lodash. Pinning exact versions is good for reproducibility and bad for patching: a security fix in a transitive dependency has to come through a Sails release or an override in your own lockfile. The exact-pin style means you should plan to track the project's releases rather than rely on caret ranges to pull fixes in.
The licence is MIT, declared in package.json and present as LICENSE.md at the repository root. MIT is permissive: it allows use, modification and redistribution with the copyright notice and permission notice retained, and it comes with no warranty. That is the extent of what the repository states. Whether MIT satisfies your organisation's policy on attribution or patent grants is a question for your legal team, not something the project answers.
Editorial conclusion
Adopt Sails.js when you want an Express-compatible Node.js API layer with WebSocket support and a single ORM abstraction across MySQL, PostgreSQL, MongoDB, Redis or local disk, and when the built-in conventions save you from assembling a router, session handling and socket wiring yourself. Do not adopt it if you need a framework with a fast-moving release cadence, since the newest release listed in the repository is v1.5.11 from 2024-05-24, or if your datastore is only reachable through a community adapter such as CouchDB, SQLite, Oracle, MSSQL, DB2, ElasticSearch, Riak, neo4j, OrientDB, Amazon RDS, DynamoDB, Azure Tables, RethinkDB or Solr, where the maintenance burden sits with someone else. Before committing, verify that the adapter for your database is the officially supported one, and read the upgrading guides on sailsjs.com for the major version you are moving from.
Frequently asked questions
How do I install Sails.js?
Install Node.js first, then run npm install sails -g to get the latest stable release of the CLI. After that, sails new my-app creates an application and sails lift starts the server.
What is Sails.js?
It is a web framework for Node.js that resembles the MVC architecture of frameworks like Ruby on Rails while targeting data-oriented web and API development. It is built on Node.js, Express and Socket.io, and the README says it is especially good for realtime features like chat.
What are the alternatives to Sails.js?
The README positions Sails as compatible with Express, so a plain Express application is the closest alternative, at the cost of assembling sessions, WebSockets and an ORM yourself. A TypeScript-first framework such as NestJS differs mainly in using decorators and dependency injection with a different ORM layer.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/balderdashy-sails)