npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

in-memory-website

v0.0.7

Published

Holds a static website in memory

Downloads

13

Readme

A static website. In memory. You can save your website to a file, serve it, or upload it to S3.

What's a "static" website? "Static" means this:

  • Only GET and HEAD requests are valid.
  • The response for a given endpoint never changes.
  • There are no errors. (A server may return 404 errors, and a server may receive erroneous HTTP requests; but those aren't website errors.)

Why "in memory"? Because it's crazy-fast for small websites. And it's better than storing the website as a bunch of files:

  • A website doesn't have "folders": it has "paths". /foo can be an HTML file, and /foo/bar can also be an HTML file. See? /foo is not a folder.
  • A website doesn't just return file contents: it also returns HTTP headers. Those headers aren't derived from the file contents.
  • A website can have redirects.

How do you take advantage? Use a framework that outputs a "static website" in this format. This package provides the tools to develop and deploy within milliseconds.

Usage

First, npm install --save in-memory-website

Now, build your in-memory website. It can be as simple as this, my-website.js:

'use strict'

const StaticWebsite = require('in-memory-website').StaticWebsite
const website = new StaticWebsite([
  { path: '/hello-world', headers: { 'Content-Type': 'text/plain; charset=utf-8' }, body: Buffer.from('Hello, World!') }
])

// ... now let's see what we can do with this website.

Local website

Now you can serve the website locally. The 404 error page is a directory listing, and any response with a Location header becomes a 301 Moved Permanently.

// ... continuing above program
const DevServer = require('in-memory-website').HttpServer
const server = new HttpServer(website)
server.listen(3000) // and browse to http://localhost:3000

Saving a website as a file

You can dump the website to a file, and then reload it later:

// ... continuing above program
const fs = require('fs')
fs.writeFileSync('my-website.bin', website.toBuffer())

// ... and in a later program
const website2 = StaticWebsite.fromBuffer(fs.readFileSync('my-website.bin'))

Lightning-fast development server

Want to code a website? Good. Here's the pattern for you. It involves three scripts:

1. build.js: builds a website; outputs to stdout

#!/usr/bin/env node
'use strict'

const StaticWebsite = require('in-memory-server').StaticWebsite
const validate = require('in-memory-server').validate

// Normally our website generator would be more complex. Potentially it will
// be asynchronous. It may throw an error. Make this script exit with a
// non-zero error code if there's a problem.
const website = new StaticWebsite([
  {
    path: '/hello-world',
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
    body: Buffer.from('Hello, World!')
  }
])

// We have utilities to avoid common mistakes. Choose the mistakes you want
// to avoid; make this script exit with a non-zero error code if there's a
// problem.
const validationError = validate.headersAreUseful(website)
if (validationError) throw validationError

// No problem? Write the website to stdout and exit with a zero error code
// (the default).
process.stdout.write(website.toBuffer())

This is your framework: the program that builds your entire website. It outputs the website to process.stdout and exits with status code 0. If it fails (for instance, your framework has a syntax error), the error is output to process.stderr.

2. dev.js: serves a website; rebuilds automatically

#!/usr/bin/env node
'use strict'

const DevServer = require('in-memory-server').DevServer

const server = new DevServer(`${__dirname}/build.js`)

// In this dev environment, let's rebuild the website every time a file changes
const chokidar = require('chokidar') // https://github.com/paulmillr/chokidar
chokidar.watch([ 'src' ])
  .on('change', () => server.queueBuild())
  .on('add', () => server.queueBuild())
  .on('unlink', () => server.queueBuild())
  // queueBuild() is "debounced": if 10 files change very quickly, we only
  // rebuild once.

server.listen(3000, err => {
  if (err) throw err
  console.log('Listening at http://localhost:3000')
})

server.listenForLiveReload() // and use http://livereload.com/extensions/

This is your development environment: the program you run in the background while you work. It's a web server, at http://localhost:3000. It has some nifty features:

  • Its "404 Not Found" page links to all the valid endpoints
  • When build.js returns a status code that isn't 0, every endpoint is a 500 Internal Server Error with debugging information.
  • It queues HTTP requests while rebuilding; those HTTP requests will complete when the build finishes.
  • If you use a LiveReload browser extension the page will refresh whenever you change a file. That means you'll see the results of your code changes immediately -- be they error messages or bugfixes.

3. deploy.js: sends a website to a production server

#!/usr/bin/env node
'use strict'

const child_process = require('child_process')
const StaticWebsite = require('in-memory-website').StaticWebsite
const S3Uploader = require('in-memory-website').S3Uploader

// Throws error if build.js fails
const websiteData = child_process.execFileSync(`${__dirname}/build.js`)
const website = StaticWebsite.fromBuffer(websiteData)

S3Uploader.uploadWebsiteToBucket(website, 'my-bucket', {}, err => {
  if (err) throw err
})

Lightning-fast production server

Hosting on S3 is cheap and fast. TODO add tutorial.

Backup production server

We supply Express middleware to help you build your own web server. For instance:

#!/usr/bin/env node
'use strict'

const express = require('express')
const StaticWebsite = require('in-memory-website').StaticWebsite
const ExpressApp = require('in-memory-website').ExpressApp

const websiteData = require('fs').readFileSync('websiteDumpedSomewhere.data')
const website = StaticWebsite.fromBuffer(websiteData)

const app = express()
app.use(ExpressApp(website))

app.listen(3000, () => { console.log('Listening at http://localhost:3000') })

License

Copyright (c) 2017 The Huffington Post, released under the MIT license. See LICENSE.