/polydev

Faster, route-centric development for Node.js apps with built-in Hot Module Replacement.

Primary LanguageJavaScript

polydev

Faster, route-centric development for Node.js apps with built-in Hot Module Replacement.

Demo GIF

Rationale

As your project grows, working on a large or monolithic Node.js app gets slower:

  • Working on part of the app means running the entire app.
  • The require tree grows so large it can take several seconds to start the server.
  • Restarting the server on every change impedes development.
  • Middleware for projects like Next.js & Storybook are expensive to restart with each change.
  • Tools like concurrently, nodemon, & piping still run the entire app.
  • You shouldn't waste time in the terminal hitting Ctrl-C and restarting.

Features

  • Fast startup.
  • Hot Module Replacement built-in.
  • Run only the parts of your app that's requested.
  • Supports yarn workspaces.
  • Pretty 404 screens with the option to create the missing route.
  • Pretty 500 screens, so you spend less time in the terminal.
  • Iterative adoption, so it's easy to get started.

Quick Started

  1. Install

    yarn add polydev --dev
  2. Run polydev

    yarn run polydev --open

For customizing the node runtime, you can use NODE_OPTIONS.

For example, TypeScript can be enabled via ts-node:

polydev --require ts-node/register
# Or
NODE_OPTIONS="--require ts-node/register" polydev

Defining routes

The routes folder is similar to Old-Time™ HTML & PHP, where folders mirror the URL structure, followed by an index.js file:

  • routes/

    • page/[id]/index.js

      Has access to req.params.id for /page/123.

    • contact-us/

      • index.get.js
      • index.post.js
    • posts/index.*.js

      Responds to both GET & POST for /posts/*.

    • index.js

      Responds to both GET & POST for /.

Route Handlers

Route handlers can be any of the following:

  1. Functional middleware:

    module.exports = (req, res) => {
      res.send("Howdy there!")
    }
  2. Express apps:

    const express = require("express")
    
    module.exports = express().get("/", (req, res) => {
      res.send(`Howdy from ${req.path}!`)
    })
  3. A yarn workspace package:

    module.exports = require("my-package-name")
  4. A package.json path:

    module.exports = require.resolve("my-app/package.json")

    These are considered stand-alone apps that will be ran via yarn dev or yarn start (whichever exists) for development only.

    This is good for when you want to have a separate API server open on process.env.PORT that's not part of your application.

Contributing

See CONTRIBUTING.md.

Author