Many popular frameworks have a function as a default export that, when called, returns an object that is considered to be the "application". After adding routes, handlers, etc., the user is able to start a server by calling a method such as .listen() or .start().

In Tuft, the functionalty of this single "application" object is split into the following two objects:

1. Route Map

This is an instance of TuftRouteMap, which is returned by the framework's default exported function, and inherits from the JavaScript Map object. It stores routes and their associated response data as key/value pairs, where the key is a string that consists of the request method and path concatenated together separated by a space (such as 'GET /foo'), or just the path (to add a route for all supported methods) and the value is an object that contains the response data.

const app = tuft()

app.set('GET /foo', {
  text: 'Hello, world!'

const myRoute = app.get('GET /foo')


// {
//   response: {
//     text: 'Hello, world!'
//   }
// }

2. Server

Once all the routes have been added to the route map, a server object can be created by calling the .createServer() or .createSecureServer() methods. When either of these methods is called, the data from the route map is compiled and made available to the returned instance of TuftServer or TuftSecureServer. The server can then be started by calling the .start() method.

const server = app.createServer()

async function startServer() {
  await server.start()
  console.log('Server has started.')