HatTip

A set of JavaScript packages for building HTTP server applications

README

HatTip


<small>(nothing)</small> Like Express.js.


Chat: Discord > CubeshashHatTip

HatTip is a set of JavaScript packages for building HTTP server applications.

- ✨ Modern: Based on current and future web standards (Fetch API & WinterCG).
- 🌍 Universal: Runs anywhere (Node.js, the Edge, Deno, ...).
- 🧩 Modular: Use as much or as little as you need.
- 🪛 Minimalist: Everything you need, nothing you don't.

It aims to build an ecosystem of universal middlewares that can be used across the entire JavaScript universe.

  1. ```js
  2. // handler.js

  3. // This request handler works anywhere, e.g. Node.js or Cloudflare Workers.

  4. export default (context) => {
  5.   const { pathname } = new URL(context.request.url);
  6.   if (pathname === "/") {
  7.     return new Response("Hello from HatTip.");
  8.   } else if (pathname === "/about") {
  9.     return new Response(
  10.       "This HTTP handler works in Node.js and Cloudflare Workers.",
  11.     );
  12.   } else {
  13.     return new Response("Not found.", { status: 404 });
  14.   }
  15. };
  16. ```

A HatTip handler is passed a context object which represents the request context and contains context.request which is a standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object. It returns a standard [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object (or a promise of one). Response and Request follow the Fetch API standard. So if you're familiar with service workers, Cloudflare Workers, or Deno, you'll feel right at home. If not, learn today the standard that will tomorrow be ubiquitous.

We believe in a diverse but interoperable future for the JavaScript ecosystem and we're closely following the WinterCG which lays the foundation beyond the Fetch API.

Adapters


- ✅ Node.js
- ✅ Cloudflare Workers
- ✅ Express.js (use HatTip handlers/middlewares in your Express.js app)
- ✅ Vercel Serverless
- ✅ Vercel Edge
- ✅ Netlify Functions
- ✅ Netlify Edge Functions
- ✅ Deno (including Deno Deploy)
- ✅ Bun
- 🚧 Service Workers

Adapters let you run HatTip on any platform. Here's how you can use HatTip with Node.js:

  1. ```js
  2. // entry-node.js
  3. import { createServer } from "@hattip/adapter-node";
  4. import handler from "./handler.js";

  5. createServer(handler).listen(3000, "localhost", () => {
  6.   console.log("Server listening on http://localhost:3000");
  7. });
  8. ```

...and on Cloudflare Workers:

  1. ```js
  2. // entry-cfw.js
  3. import cloudflareWorkersAdapter from "@hattip/adapter-cloudflare-workers";
  4. import handler from "./handler.js";

  5. export default {
  6.   fetch: cloudflareWorkersAdapter(handler),
  7. };
  8. ```

You can even use your HatTip application as an Express middleware when you have to use that one Express library that doesn't have a replacement anywhere else:

  1. ```js
  2. // entry-express.js
  3. import { createMiddleware } from "@hattip/adapter-node";
  4. import handler from "./handler.js";
  5. import express from "express";
  6. import oldAndRustyExpressMiddleware from "old-and-rusty-express-middleware";

  7. const hattip = createMiddleware(handler);
  8. const app = express();

  9. // TODO: Replace with shinyNewHatTipMiddleware once ready
  10. app.use(oldAndRustyExpressMiddleware());
  11. app.use(hattip);

  12. app.listen(3000, "localhost", () => {
  13.   console.log("Server listening on http://localhost:3000");
  14. });
  15. ```

Middleware system


The compose function from the [@hattip/compose](./packages/compose) package can be used to compose multiple handlers into a single one, creating a simple but powerful middleware system. Each handler is called in sequence until one returns a response. A handler can pass control to the next handler either by not returning anything or calling ctx.next(). The latter allows the handler to modify the response before returning:

  1. ```js
  2. import { compose } from "@hattip/compose";

  3. // Example of making things available in `ctx`
  4. // Middleware to parse the URL into a URL object
  5. const urlParser = (ctx) => {
  6.   ctx.url = new URL(ctx.request.url);
  7. };

  8. // Example of modifying the response
  9. // Middleware to add an X-Powered-By header
  10. const poweredBy = async (ctx) => {
  11.   const response = await ctx.next();
  12.   response.headers.set("X-Powered-By", "HatTip");
  13.   return response;
  14. };

  15. // HatTip does have a router, this is to illustrate the basics
  16. const homeHandler = (ctx) => {
  17.   if (ctx.url.pathname === "/") {
  18.     return new Response("Home");
  19.   }
  20. };

  21. const fooHandler = (ctx) => {
  22.   if (ctx.url.pathname === "/foo") {
  23.     return new Response("Foo");
  24.   }
  25. };

  26. const barHandler = (ctx) => {
  27.   if (ctx.url.pathname === "/bar") {
  28.     return new Response("Bar");
  29.   }
  30. };

  31. export default compose(
  32.   urlParser,
  33.   poweredBy,
  34.   homeHandler,
  35.   fooHandler,
  36.   barHandler,
  37. );
  38. ```

A handler can return or throw a Response or anything with a toResponse method when used with the compose function. Handlers can also set context.handleError to handle uncaught errors.

That's it. This is the entirety of the HatTip API. Everything else is middleware functions similar the above that add various features and development tools to make your life easier.

Packages


HatTip is extremely modular so you can use as little or as much as you need:

- [core](./packages/base/core): A type-only package that defines the interface between your application and platform adapters
- Adapters: Enable HatTip to run on any platform:
  - [adapter-node](./packages/adapter/adapter-node): Node.js, either as a standalone server or as a middleware function that can be used with Express and similar frameworks. Also works for Vercel Serverless Functions.
  - [adapter-cloudflare-workers](./packages/adapter/adapter-cloudflare-workers): Cloudflare Workers
  - [adapter-vercel-edge](./packages/adapter/adapter-vercel-edge): Vercel Edge Functions
  - [adapter-netlify-functions](./packages/adapter/adapter-netlify-functions): Netlify Functions
  - [adapter-netlify-edge](./packages/adapter/adapter-netlify-edge): Netlify Edge Functions
  - [adapter-deno](./packages/adapter/adapter-deno): Deno
  - [adapter-bun](./packages/adapter/adapter-bun): Bun
- Bundlers: Worker and serverless platforms usually require your code to be in bundled form. These packages provide bundlers fine-tuned for their respective platforms:
  - [bundler-cloudflare-workers](./packages/bundler/bundler-cloudflare-workers): Cloudflare Workers
  - [bundler-vercel](./packages/bundler/bundler-vercel): Vercel edge and serverless functions
  - [bundler-netlify](./packages/bundler/bundler-netlify): Netlify edge and Netlify functions
  - [bundler-deno](./packages/bundler/bundler-deno): Deno
- Low-level stuff
  - [polyfills](./packages/base/polyfills): A collection of polyfills used by adapters for compatibility across platforms
  - [compose](./packages/base/compose): A middleware system for combining multiple handlers into a single one
- Utilities and middleware
  - [router](./packages/base/router): Express-style imperative router
  - [response](./packages/base/response): Utility functions for creating text, JSON, and HTML responses
  - [cookie](./packages/middleware/cookie): Cookie handling middleware
  - [cors](./packages/middleware/cors): CORS middleware
  - [graphql](./packages/middleware/graphql): GraphQL middleware
  - [session](./packages/middleware/session): Session middleware

A zero-config development environment based on Vite is also in the works

Credits



- Code and concept by Fatih Aygün, Romuald Brillout, and contributors.
- Logo and branding by Aydıncan Ataberk.
- The [cors](./packages/middleware/cors) package is a port of koajs/cors by koajs and contributors under the MIT License. They are not affiliated with HatTip.
- The [graphql](./packages/middleware/graphql) package comes bundled with @graphql-yoga/common which is part of the GraphQL Yoga project by Graphcool, Prisma, and The Guild, under the MIT License. They are not affiliated with HatTip.