# restify: the Node framework that would not become Express

> A connect-style REST framework with API versioning, DTrace instrumentation and a long release gap, still shipping after twenty years in Node.

**restify/node-restify** — The future of Node.js REST development

- Repository: https://github.com/restify/node-restify
- Website: http://restify.com
- Stars: 10,687 · Forks: 974
- Language: JavaScript
- License: MIT
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/restify-node-restify

## Building a server the way Connect taught people to

The README's server example is short enough to memorise. You create a server with a name and version, register three parser plugins, define a route with a path parameter, and listen. There is no application object separate from the server, no global middleware stack to configure, and no async error handling ceremony.

```javascript
var restify = require('restify');

const server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});

server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.queryParser());
server.use(restify.plugins.bodyParser());

server.get('/echo/:name', function (req, res, next) {
  res.send(req.params);
  return next();
});
```

Three points are worth noticing. The `name` and `version` passed to `createServer` are not decoration, they become the server version response that clients negotiate against. `acceptParser` is what makes that negotiation possible, since it parses the incoming Accept header and rejects an unsupported media type rather than silently sending JSON to a client that cannot read it. And the handler signature ends in `next`, which is the Connect convention restify adopted wholesale, described in the README as using connect style middleware.

The third argument existing at all is the main ergonomic difference from Express. In Express you write async handlers and rejected promises become unhandled rejections. In restify, calling `next` is how you say you are finished, and forgetting it stalls the request rather than returning a response.

## What API versioning actually does for a consumer

The version you pass to `createServer` is the mechanism behind restify's original motivation, which was to give HTTP APIs a first-class answer to versioning instead of bolting one on later. restify will emit an `Accept-Version` header on outgoing requests, it exposes the negotiated version on the request object, and it can be configured to reject a request carrying a version it does not support rather than serving the wrong shape of payload.

This is the feature that most distinguishes restify from a generic Connect-style framework. The trade-off is that it is only useful if your clients are as disciplined as your server. A public API consumed by browser JavaScript that ignores versioning headers gains nothing from the machinery, and pays the small complexity cost of maintaining it. An API consumed by three internal mobile teams that each pinned a version is exactly where the machinery pays for itself, because a breaking change becomes a negotiated response rather than an outage.

The client half of the package is a separate module, `restify-clients`, and the README pairs the two. The client negotiates against a version range rather than a fixed string:

```javascript
var clients = require('restify-clients');

var client = clients.createJsonClient({
  url: 'http://localhost:8080',
  version: '~1.0'
});
```

The tilde prefix is semver range syntax, asking for any 1.x release rather than exactly 1.0.0.

## Two and a half years between major releases

The release history is the most interesting thing in the repository, and it needs reading carefully. Version 11.2.0 shipped on 2024-01-27. Version 12.0.0 shipped on 2026-08-25, labelled a security-and-breaking release with four breaking changes: two upgrades of the `qs` query string library, added support for Node.js 26, and removal of the deprecated spdy protocol.

Between 9.1.0 in mid-2023 and 11.2.0 there is no 10.x in this list, so either releases were made from a branch not represented here or the numbering moved. What the sequence does establish is that this is a project with long quiet stretches followed by concentrated bursts of maintenance, and that the bursts are driven by dependency and runtime obligations rather than by feature demand. The 12.0.0 changes are almost all of that kind: upgrade a transitive library, support a new Node, drop a protocol nobody should have been using.

The removal of spdy is the most consequential for anyone running it in production, because spdy was a multiplexed HTTP/2 precursor and the README's supported Node versions line has since moved on. The `examples/http2/` directory in the tree suggests the modern answer is HTTP/2 rather than spdy. The `benchmark/` directory and a `Makefile` target for running it are also present, so performance comparisons the project has run are reproducible if you want them.

## Node support, observability and the parts of the tree that explain the design

The README states that restify currently works on Node.js v22.x, v24.x and v26.x. That is a narrow, current support window rather than an open-ended compatibility claim, and it is worth treating as a hard constraint in your deployment target. The 12.0.0 release adding Node.js 26 support, alongside replace deprecated node apis, tells you the project is tracking the removal of Node APIs rather than resisting them.

The repository tree has a few directories that explain where the project's personality comes from. `bin/` is the command line client, `benchmark/` holds performance harnesses, and `examples/` contains seven runnable samples including dtrace, http2, jsonp, sockio and a todoapp. The dtrace example is the interesting one on macOS: the `DTrace` keyword appears in the package.json keyword list, and the project originated at Joyent, where DTrace was a first-class debugging tool. That lineage explains an inclination toward introspection that Express, built as minimal middleware, does not share.

Documentation lives in `docs/` with a build step wired through `tools/docsBuild.js` in the Makefile, and `test/` is split so that plugin tests run under Mocha while the main suite runs under nodeunit. That dual-runner setup is a fossil: it reflects a codebase assembled over years rather than rewritten, and it is the kind of detail that tells you the test suite predates the current tooling preferences of the maintainers.

## Why this exists instead of just using Express

The comparison everybody reaches for is Express, and it is the right one. Both use Connect-style middleware, both have been in Node since before the async era, and both are MIT licensed with large install counts. The difference is intent. Express minimised everything, on the theory that a web framework should stay out of the way. restify narrowed in on a specific shape of problem, HTTP APIs consumed by programs rather than by browsers, and accepted some opinionation in exchange.

What you get for that opinionation is the versioning machinery described above, plus response formatting and query parsing that are consistent by default rather than assembled from middleware. What you give up is the size of the ecosystem. Express's middleware ecosystem is the reason most teams end up there, and the probability that a package you already use ships an Express integration but not a restify one is high.

There is also a simpler reason to choose Express that has nothing to do with features: most Node developers already know its error handling and its middleware ordering. restify's `next()` convention is correct and explicit, but it is a different thing to hold in your head while debugging at midnight. The project is 10,687 stars with 975 forks and 132 open issues, so it is not abandoned, and the last push was 2026-09-04. It is a maintained alternative, not a growth story.

## Conclusion

restify is a good fit when you are publishing an API that other teams build against, because versioning and response headers are part of the design rather than bolted on. It is a poor fit for a general-purpose web application, where Express's middleware ecosystem is simply larger. The thing to verify before adopting it is the dependency surface: the package pulls in a specific router and query string library, and the 12.0.0 release upgraded both as breaking changes, so a pin to a specific version is worth more than a floating range in a package.json.

## FAQ

### What is the Node.js REST framework?

Several Node frameworks describe themselves that way, and the most widely used is Express. restify is another, built around Connect-style middleware and aimed specifically at HTTP APIs consumed by programs rather than browsers. Its distinguishing feature is first-class API versioning, where the version passed to createServer becomes a negotiated response header rather than an application convention.

### How do you install restify?

Through npm, with npm install restify. The README states that restify currently works on Node.js v22.x, v24.x and v26.x, so check your runtime version against that window before installing. The client half of the package is a separate module called restify-clients.

### What are the main differences between restify and Express?

Both use Connect-style middleware and both are MIT licensed. restify is opinionated toward versioned HTTP APIs and ships versioning, response formatting and query parsing as built-in behaviour. Express is deliberately minimal and has a far larger middleware ecosystem, so the practical difference for many teams is package availability rather than capability.

### Which Node.js versions does restify support?

The README says v22.x, v24.x and v26.x. Version 12.0.0 added Node.js 26 support and replaced deprecated Node APIs, which indicates the project tracks Node's API removals rather than maintaining broad backwards compatibility.

## Sources

- [License: MIT](https://github.com/restify/node-restify/blob/master/LICENSE)
- [Project website](http://restify.com)
- [README](https://github.com/restify/node-restify/blob/master/README.md)
- [Releases](https://github.com/restify/node-restify/releases)
- [restify/node-restify on GitHub](https://github.com/restify/node-restify)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/restify-node-restify
