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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@light-arrow/express

v0.2.0

Published

arrow bindings for express

Downloads

2

Readme

About

Light Arrow is a small library for type safe asynchronous programming in typescript. The library is based around the functional and composable Arrow data type. Arrows are data structures that describe asynchronous (and synchronous) operations that can succeed or fail and may have some dependencies. Please check out the documentation https://lauri3new.github.io/light-arrow-docs/ for a longer explanation and some examples.

This module exposes helper functions for building type safe http apps using the express framework and the Arrow data type. Please see this section https://lauri3new.github.io/light-arrow-docs/docs/HttpApp of the documentation for more detail, and this section https://lauri3new.github.io/light-arrow-docs/docs/Arrow for more on the Arrow data type.

Getting Started

Installation

npm install @light-arrow/arrow @light-arrow/express

Light-arrow/express provides bindings for writing type safe http apps. Instead of using native response methods we can instead describe the http response using a Result data type.

An HttpApp is simply a (ctx: Context) => Promise<Result>. To help with type safety and composability we can define HttpRoutes as Arrow<Context, notFound | Result, Result> and then use the seal function, providing handlers for 'not found' and exception cases. We can then bind an HttpApp to an express instance using the bindApp function, providing any dependencies the Arrows require at that time if we want.

interface Context {
  req: Request
}

We can express our whole express app using Arrows. Middlewares can be defined as Arrow<A, Result, B> where A and B extend the context. Multiple middlewares can be stacked together in a type safe manner using the andThen function. By defining our middleware this way we can expand and transform the context in a composable and type safe way, for example attaching services or authorisation data to the context.

An example Middleware

const authorizationMiddleware: Arrow<Context, Result, {
  loggedIn: boolean;
  req: Request;
}> = draw((ctx: Context) => {
  if (ctx.req.headers.authorization) {
    return succeed({ ...ctx, loggedIn: true })
  } else {
    return fail(Unauthorised({}))
  }
})

Handlers can be written as Arrow<A, Result, Result> where A is inferred from the middlewares. HttpRoutes are then Arrows of Type Arrow<A, notFound \ Result, Result>, and we can combine HttpRoutes together (similar to how we would use an express Router) using the orElse function.

An example HttpRoute

const getUsers: Arrow<{
  loggedIn: boolean;
  req: Request;
}, NotFound, Result> = get('/users')
  .andThen(draw((ctx: Context) => ctx.services.getUsers()))

Multiple routes and middlewares combined

const routes: Arrow<Context, NotFound | Result, Result> = orElse(
  get('/healthcheck').map(() => OK({})),
  authorizationMiddleware.andThen(
    orElse(
      getUsers,
      getTimeline
    )
  )
)

Converting HttpRoutes to an HttpApp

const httpApp = seal(
  routes,
  () => NotFound({
    message: 'not found'
  }),
  () => InternalServerError({
    message: 'oops something went wrong'
  })
)

Binding our HttpApp to an express instance

const expressInstance = express()
const { app } = bindApp(httpApp)(expressInstance)

app.listen(8080)

Once we have all the routes described we can convert the HttpRoutes to an HttpApp using the seal function, providing functions for converting the notFound type and runtime exceptions into http Results. We can then use the bindApp function to attach our httpApp to an express application instance and inject dependencies.