
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
micro-extensions
Advanced tools
Tools for building Node.js apps with Zeit's Micro
Micro defines a set of powerful primitives for building endpoints with Node.js. Micro extensions provides additional functions and helpers that extend Micro's core making it easy to weave together small applications into larger ones.
Note: we currently transpile using babel until Node.js 8 comes out then will deprecate transpiling and the need to reach into lib/ to reach things that are not exported from main.
Micro extensions also extend Micro, which is very unopinionated, with one important principle:
State mutation and other side-effects must be isolated and explicit
import { configureRoutes } from 'micro-extensions/lib'
const routes = configureRoutes({
routes: [
{ method: 'get', pattern: '/foo', handler: fooHandler },
{ method: 'get', pattern: '/foo/fuzz', handler: fuzzHandler },
...notFoundRoutes
],
effects: { database },
middlewares: [ logRequests ]
})
const app = createApp(routes)
micro(app).listen(2222)
Everything in Micro extensions is made to work well together or separately as much as possible.
A flexible router for declaratively composing request handlers, effects, middleware and application configs into applications.
See router.
Request handlers accept a context object containing the familiar req and res as well as any applicable effects and/or application config. This avoids the common Node.js practice of mutating the req object to maintian context and promotes explicit declaration of a request handler dependencies. See request handlers.
Side-effects are first class concepts that materialize in Micro extensions as helpers called "effects". Effects are injected into request handlers at runtime providing well defined interfaces over state mutations and other side-effects, e.g.:
const createFooHandler = async ({ req, res, effects: { apiClient } }) => {
return await apiClient.post('https://api.foo.com/foos', { bar: true })
}
Some common effects are provided out of the box:
Effects have access to the request context and can also be used in middleware. See effects.
Middleware are functions that wrap response handlers. Middleware have access to a full response handler context object. See middleware.
Helpers for loading and validating application configurations. See application config.
The approach of Micro makes testing incredibly easy. Some helpers are provided to help reduce boilerplate. See testing.
A helper app is provided for generating documentation from code. See documentation.
Reusable sub applications can be easily created by exporting a call to configureRoutes allowing you to package routes, effects, and middleware into a set of routes for reuse in larger applications which can supply the application configuration as well as additional effects and middleware. See plugins.
Routes are arrays of route declarations. Each route declares an HTTP method, a path pattern, and a handler to invoke for matching requests, e.g.:
const routes = [
{
method: 'get',
pattern: '/foo/:fooId',
handler: ({ params: { fooId } }) => ({ ok: true, fooId })
},
{ method: 'all', pattern: '/*', handler: () => { throw createError(404, 'Not Found') } }
]
See route declarations to learn about the structure of a route.
configureRoutes(routes, { effects = {}, middlewares = [], config = {} })Configure a set of routes with effects, middleware and application config.
Arguments
routes are an array of route definitionseffects are a map of effect names to objectsmiddlewares are an array of middleware functionsconfig an application configuration objectsReturns
A flattened array of route definitions
createApp(routes)Creates a Micro-compatible handler from an array of route definitions.
Arguments
routes are an array of route definitionsReturns
A Micro-compatible request handler
mountAt(prefix, routes)Adds a path prefix to a set of routes.
Arguments
prefix is string describing the path each route should be prefixed with.
routes are an array of route definitionsReturns
An array of route definitions
A route declaration describes a URL pattern and HTTP verb combination along with a handler for matching requests.
method any HTTP verb or "all" to handle any verbpattern a url pathname pattern
paramshandler a request handler to invoke for matching requestsUsers are encouraged to consider if desired behavior can be achieved with effects because they encourage explicit calls inside requests handler code rather than introducing the indirection that comes with middleware. With that said it's easy to define new middleware when you want to apply some behavior to one more more routes unobtrusively, e.g.:
const logMiddleware handler => ({ effects: { logger } }) => {
logger.info('Yay, someone invoked me!')
}
Some generally useful middleware is provided
Arguments
handler request handler to be wrapped by middlewareReturns a request handler
Micro extensions embraces the concept of "rich request handlers" which can be found in Next.js. The only difference is that instead of the typical Node.js request handler that accepts a req as its first argument and res as its second argument it receives a single context object with req and res as top-level attributes.
Before:
const fooHandler = (req, res) => ({ ok: true })
After:
const richFooHandler = ({ req, res, query }) => ({
ok: true,
foo: query.foo
})
req vanilla Node.js request objectres vanilla Node.js response objectquery object of key/value pairs parsed out of the URL query stringparams object of key/value pairs parsed out of any named parameters in the requested URLpathname the pathname of the requested URLconfig application config object config objecteffects object where the keys are the names of side-effects and the values are effects helpersAdopting the convention of passing a context object into a handler counteracts the common approach across Node.js frameworks of mutating the request object as a way for different parts of the application to coordinate (e.g. express session middleware adds a session attribute to req and expects you to find it by convention in handlers). There's no great problem with this but it forces your application to depend on a "proprietary" req object and ultimately leads to indirection that makes it harder to reason about. On the other hand, by accepting a context object, libraries (like the included router) can add to the context of the request without having to rely on reading/writing to the request object. E.g. the application config is made available to all requests as a top level key:
const configurableFooHandler = ({
req,
res,
config: { apiUrl }
}) => ({
apiUrl,
ok: true
})
suppressConsoleError()Adds a beforeEach and afterEach to suppress all calls to console.error during test run. Used to quiet Micro tests that invoke sendError.
There's no specific documentation for plugins because to create one you simply export a call to configureRoutes from a module.
Some plugins ship with Micro extensions:
FAQs
Tools for building Node.js apps with Zeit's Micro
We found that micro-extensions demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.