Skip to content

mkantor/loom

Repository files navigation

loom

Loom is a web server for Node.js. Web pages in Loom use Silk for server-side rendering.

Loom has filesystem-based routing: when you start the server you provide a directory containing static files and dynamic request handlers which are used to serve incoming HTTP requests.

The server avoids buffering response data as much as possible, instead streaming it to the client as soon as it becomes available.

Example websites powered by Loom & Silk are available in this repository: https://github.com/mkantor/silk-demos.

Quick Start

This creates a basic "hello world" website:

npm create loom@latest $path
cd $path
PORT=9999 npm run start

There should now be web server running at http://localhost:9999.

Usage

createServer

Initializes the Loom server, returning an object with a .listen method that you can call to bind it to a specific port.

createServer is passed a configuration object with a required publicDirectory property (more on this below) and other optional properties to specify the server's behavior.

Example:

const server = createServer({
  publicDirectory: 'path/to/public/directory',
})
await server.listen(80)

The Public Directory

The "public directory" is the folder in your project which corresponds to the root of Loom's filesystem-based routing scheme. In Loom, the request method is treated as part of the route, and the public directory is therefore expected to have a top-level subdirectory for each HTTP method that you want to handle (public/get/, public/post/, etc).

File naming conventions within the public directory specify how Loom treats the file:

  • Files whose names end in #handler.js (typically compiled from a source file named #handler.tsx) are dynamic request handlers which may include server-side logic. Such files should have a default export created via the page or requestHandler functions (see below). This filename suffix may be customized via the handlerFilenameSuffix configuration option. Everything preceding this suffix corresponds to the request path, meaning your top-level index page would be served by public/get/#handler.js (an empty prefix), and an /about page could either be handled by public/get/about#handler.js or public/get/about/#handler.js.
  • A file at the root of the public directory named #error.js (usually the emit of a source file named #error.tsx) can be used to implement custom error pages. This file should have the same structure as request handlers. The path/filename of this file may be customized via the errorHandler configuration option.
  • All other files in the public directory are treated as static files and are served directly.

page & requestHandler

The default export of dynamic handler modules should be wrapped in a page or requestHandler call.

Example:

export default page(request => (
  <html lang="en">
    <head>
      <title>Greeting</title>
    </head>
    <body>Hello, world!</body>
  </html>
))
  • Use page if you need a dynamic response body but want Loom to take care of the response headers/status code. The value you return should be a ReadableHTMLStream (likely generated by Silk).
  • Use requestHandler if you want full control over the entire response, including headers/status code/etc. The value you return should be a complete Response object.

About

Stream-oriented web server with filesystem-based routing

Resources

License

Stars

Watchers

Forks

Packages

No packages published