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.
This creates a basic "hello world" website:
npm create loom@latest $path
cd $path
PORT=9999 npm run startThere should now be web server running at http://localhost:9999.
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" 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 thepageorrequestHandlerfunctions (see below). This filename suffix may be customized via thehandlerFilenameSuffixconfiguration option. Everything preceding this suffix corresponds to the request path, meaning your top-level index page would be served bypublic/get/#handler.js(an empty prefix), and an/aboutpage could either be handled bypublic/get/about#handler.jsorpublic/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 theerrorHandlerconfiguration option. - All other files in the public directory are treated as static files and are served directly.
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
pageif you need a dynamic response body but want Loom to take care of the response headers/status code. The value you return should be aReadableHTMLStream(likely generated by Silk). - Use
requestHandlerif you want full control over the entire response, including headers/status code/etc. The value you return should be a completeResponseobject.