Library / SDK
florianholzapfel/express-restify-mongoose avatar
florianholzapfel/express-restify-mongoose

express-restify-mongoose turns a mongoose model into a REST surface

Easily restify mongoose databases

642 stars149 forksJavaScriptMIT

At a glance

What is it?
express-restify-mongoose generates a flexible REST interface from a mongoose model so that a Node service can expose CRUD endpoints without hand-writing routes, and its compatibility matrix and nine-major version history show how much of the value depends on matching your stack.
Who is it for?
express-restify-mongoose fits a Node team that wants a working CRUD surface for a mongoose model this afternoon rather than a week of route boilerplate, particularly for an internal service or a prototype with a documented API site to match. It does not fit a codebase whose endpoints have bespoke shapes, custom authorisation per route or non-CRUD semantics, because a generated surface is the wrong shape for those.
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 10 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 October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the library generates for a mongoose model

express-restify-mongoose exists to do one job: create a flexible REST interface for mongoose models. The name is a piece of history in itself, since it pairs Express with restify, and the library's job is to bind a mongoose model to HTTP routes so that the CRUD surface exists without anyone writing the handlers.

The word doing the work in the description is flexible. A generated API is a blunt instrument: it tends to expose exactly the shape of the model, which is fine for an internal service and wrong for a public API where responses need to be a contract independent of the database document. The documentation site at florianholzapfel.github.io/express-restify-mongoose is the actual reference for what can be configured, and the repository carries an examples directory with an invoicing example, which is the kind of sample that shows how the generated endpoints compose into a domain API.

The project is small in structure and old in origin. The licence block dates the work to 2013, the package has been published under the same name since the restify era, and the modern version history in the repository shows it has been carried forward rather than rewritten.

Installing the package and where the documentation lives

The install step is a single npm command, and the documentation is a GitHub Pages site rather than a README:

sh
npm install express-restify-mongoose --save

The README points to https://florianholzapfel.github.io/express-restify-mongoose/ for the full documentation, which is where the configuration options live. That is a meaningful detail for an evaluating team: a library whose main reference is a separate site is one where the shipped docs and the source can drift apart, and where a search for a configuration key sends you to a site rather than to a file in the repository.

The repository itself is small and conventional for a TypeScript library that ships JavaScript. There is an index.d.ts and an express.d.ts at the root, a src/ directory, a test/ directory, tsconfig.json, .swcrc, .eslintrc and a yarn.lock, so the package is developed as TypeScript and published as compiled output.

The compatibility table is the first thing to read

The README leads with a compatibility matrix rather than a feature list, which is the correct priority for a library whose whole job is to sit between two other libraries that both move.

The table maps library versions to Mongoose, MongoDB and NodeJS versions:

markdown
| This library |  Mongoose   |   MongoDB   |  NodeJS
| ------------ | ----------- | ----------- | --------
| >= 10.0.0    | 8.x         | 5.x - 8.x   | >=22
| >= 9.0.0     | 6.x - 8.x   | 3.6.x - 7.x | >=16
| >= 8.0.0     | 6.x         | 3.6.x - 6.x | >=18

Two observations matter. The 10.x line requires Node 22 or newer, which is a real constraint for a team still on an older runtime, and the Node column is not monotonic across the rows, since the 8.x line asks for Node 18 while the 9.x line only asks for 16. So the right version is not simply the newest one that supports your Node.

The table also extends back to 0.7.5, which covers mongoose 3.x, MongoDB 2.4 to 3.0 and any Node version. The library has been carried across four generations of mongoose and roughly a decade of Node releases, and that continuity is the strongest argument for it: it has been updated rather than abandoned.

TypeScript source, swc output and hand-written declarations

The build scripts describe the pipeline in full:

json
    "build": "run-p build:*",
    "build:cjs": "swc src --config module.type=commonjs --out-dir dist",
    "build:dts": "tsup src/express-restify-mongoose.ts --dts-only",

Source is TypeScript, transpiled to CommonJS by swc into dist, with type declarations produced separately by tsup. The published entry point is the dist bundle, and the files array limits the published package to dist/. A separate tsc script runs tsc with --noEmit, so type errors are caught without emitting, and the lint script runs eslint over .js and .ts files.

The runtime dependencies are few and tell you what the library actually does: mongoose at ^8.22.1 for the model binding, zod at ^3.19.1, dot-prop at ^6.0.0, lodash.isplainobject and serialize-error. zod is the interesting one, since it gives the library a way to validate and parse request payloads rather than trusting them, and dot-prop gives access to nested properties by path, which is what a generic filter mechanism needs. serialize-error is there to turn an Error into something safe to put in a JSON response.

The TypeScript surface is not only the generated declarations. There is an express.d.ts at the root as well as index.d.ts, which suggests the library augments or describes Express types rather than only exporting its own.

Three test suites, one of them an integration filter test

The test scripts are split by what they exercise:

json
    "test": "run-s test:*",
    "test:express": "mocha -R spec ./test/express.mjs --timeout 10s",
    "test:filter": "mocha -R spec ./test/integration/resource_filter.mjs --timeout 10s",
    "test:unit": "mocha -R spec ./test/unit.mjs",

The unit suite runs the logic, the express suite runs the HTTP surface, and the filter suite is an integration test in its own directory, which suggests filtering and querying is the part of the behaviour with enough edge cases to deserve its own file. The ten second timeout on the two suites that touch Express and the filter path is a hint that they start an in-process server.

The build itself is driven by npm-run-all, with run-p for the parallel build steps and run-s for the sequential test steps, and the test scripts run in sequence.

Contributing is described in the README rather than in a separate file, and it asks for the standard style, the feross/standard JavaScript style, plus a pull request. The repository also carries a CHANGELOG.md, which for a package of this age is where the behaviour changes between versions are recorded.

The alternative is hand written routes, and it wins on contract clarity

The alternative to generating a REST surface is writing the Express routes yourself, or reaching for a contract-first tool that generates clients from a schema. Both give you something the generated surface cannot.

A hand written route makes the response shape explicit. You decide what a client sees, independent of the mongoose document, and you decide the status codes, the error body and the validation rules per endpoint. The generated surface inverts that: the model is the contract, and the contract moves when the model moves, which is a problem the moment a second consumer appears or the moment the database schema is refactored for its own reasons.

The generated approach wins on speed of first result. One model, a few lines of registration, and you have listing, filtering, creation, update and deletion endpoints with the query parameters already handled. For an internal service, a prototype, or a data API whose consumers are your own frontend, that is often the whole requirement.

The decision usually comes down to one question: is the API a contract for someone outside the codebase? If yes, write the routes. If the model is the API and only your own code reads it, generate it.

One more difference is worth weighing. A generated API needs validation and authorisation thought through carefully, because the endpoints exist whether or not you designed them. Hand written routes fail closed by default, since an endpoint that does not exist returns nothing.

MIT terms and a version history that has moved more than once

The library is released under the MIT Licence, with the full permission notice dated 2013 by Florian Holzapfel in the README and the LICENSE file at the repository root. MIT is the permissive end of the licence spectrum, so a service built on this library carries no distribution obligation beyond the notice.

The version history shows the churn. The most recent published release is 9.0.13 on 2026-07-17, before it 9.0.10 on 2025-09-23 and 9.0.5 on 2024-10-29. The repository is not archived and the last push was on 2026-10-13.

There is a mismatch worth noting between the published releases and the repository state. The package.json in the tree declares version 9.0.11, which is behind the 9.0.13 on the registry, and the compatibility table already describes a 10.x line that requires Node 22 or newer and does not appear in the release list. In other words, the trunk contains work that is neither the published 9.0.13 nor a released 10.0.0.

Practically, that means pinning 9.0.13 gives you the newest published artifact, and 10.x should be treated as unreleased unless you find a tag for it. The dependencies also pin mongoose at ^8.22.1, so a project still on mongoose 6 or 7 is outside the supported range of the current line and should look at the 9.0.0 row of the table.

Editorial conclusion

express-restify-mongoose fits a Node team that wants a working CRUD surface for a mongoose model this afternoon rather than a week of route boilerplate, particularly for an internal service or a prototype with a documented API site to match. It does not fit a codebase whose endpoints have bespoke shapes, custom authorisation per route or non-CRUD semantics, because a generated surface is the wrong shape for those. Before installing, read the compatibility table against your Node, Mongoose and MongoDB versions, and note that the newest published release shown is 9.0.13 while the table already describes a 10.x line requiring Node 22 or newer.

Frequently asked questions

How do I install express-restify-mongoose?

The documented install command is npm install express-restify-mongoose --save. The full documentation is hosted at florianholzapfel.github.io/express-restify-mongoose rather than in the README.

Which versions of Mongoose, MongoDB and Node does the latest release support?

The compatibility table shows the 10.x line with Mongoose 8.x, MongoDB 5.x to 8.x and Node 22 or newer, and the 9.x line with Mongoose 6.x to 8.x, MongoDB 3.6.x to 7.x and Node 16 or newer. The newest published release shown is 9.0.13, published on 2026-07-17.

Does express-restify-mongoose validate request data?

The runtime dependencies include zod, along with dot-prop, lodash.isplainobject and serialize-error, alongside mongoose. The library binds a mongoose model to HTTP routes so you do not have to write the CRUD handlers yourself.

How is the package built and tested?

The source is TypeScript transpiled to CommonJS with swc, and type declarations are produced with tsup. Tests run through mocha in three suites, unit, express and an integration resource filter suite, driven by npm-run-all.

What licence is express-restify-mongoose released under?

It is released under the MIT Licence, with the permission notice in the README dating from 2013 by Florian Holzapfel and a LICENSE file at the repository root.

Official sources

  1. florianholzapfel/express-restify-mongoose on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/florianholzapfel-express-restify-mongoose.svg)](https://hysenlabs.com/projects/florianholzapfel-express-restify-mongoose)

Was this useful?