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

express-functions

v2.0.0

Published

An express library for making it easy to connect backend and frontend of modern web applications via functions and events

Downloads

11

Readme

Express Functions

An expressjs library for making it easy to connect backend and frontend of modern web applications with functions.

Getting started

First, we need to setup our backend.

Backend

Install express and express-functions

$ npm install express express-functions

Create our server files

// ./app.js

const express = require('express');
const path = require('path');
const exprFn = require('express-functions');

const app = express();

// for serving the index.html and frontend js file
app.use(express.static(path.join(__dirname, '/public/')));

// import the server functions
// we're not gonna use events now
app.use(exprFn({
  events: false,
  functions: require('./functions')
}));

// start the server
const port = process.env.PORT || 8080;
app.listen(port, () => console.log('Server is running'));
// ./functions.js

// export an object with your functions
module.exports = {
  greet({ name }) {
    return `Hello ${name}, you're welcome!`;
  },
  add({ a, b }) {    // use object-destructuring for
    return a + b;    // parameters
  }
}
// ... thats it!

Frontend

For the frontend we need to add the frontend file. You can find it at the releases tab on github.com. Just download the file or use a CDN (used in the example).

Now the index.html file

<!-- ./public/index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>ExpressFunctions</title>
</head>
<body>
  <!-- Add express-functions script -->
  <script src="https://unpkg.com/express-functions/src/public/expr-fn.js"></script>

  <script>
    // put the code in an async function
    async function main() {
      // connect to the backend
      const backend = await exprfn.connect();
      // call the add function (functions.js)
      const addResult = await backend.call('add', { a: 5, b: 3 });
      console.log(addResult);
      // call the greet function
      const msg = await backend.call('greet', { name: 'John Doe' });
      console.log(msg);
    }

    // call the main function
    main();
  </script>
</body>
</html>

And thats all you got to do for getting your frontend and backend to communicate via functions. You can transfer data, work with it on the server and send it back to the user.

Using Events

If you want to use events, we need to set-up a bit more mostly on the front-end.

First, on the back-end

// app.js

// ...

app.use(exprFn({  // when configuring ExpressFunctions, change the
  events: true    // events attribute to: "true"
}));              // boom, thats all

// ...

The Front-End

Lets trigger an event and catch it again. This doesn't make much sense if it happens on the same page, but it gets the point across...So lets edit the index.html file:

<!-- ./public/index.html -->

<!-- ... -->
<body>
  <h1 id="output"></h1>

  <script src="https://unpkg.com/express-functions/src/public/expr-fn.js"></script>

  <script>
    main();

    async function main() {
      const backend = await exprfn.connect();

      // listen for the myMessage-Event ...
      backend.on('myMessage', (resp) => {
        // ... and output the result
        document.getElementById('output').innerHTML = resp.msg;
      });

      // use .once and .then if you the event only happens once:

      // backend.once('myMessage')
      //   .then(resp => {
      //     document.getElementById('output').innerHTML = resp.msg;
      //   });

      // lets emit the event every second
      setInterval(() => {
        const randInt = Math.floor(Math.random() * 10);
        backend.emit('myMessage', { msg: `RandInt: ${randInt}` });
      }, 1000);
    }
  </script>
</body>
<!-- ... -->

And as expected, every second a new number appears on the screen.

Backend Docs

The express-functions package exposes a function to use. Add it to express via app.use(require('express-functions')(/* options */));.

Options

  • events (Boolean): true if you want to use events, false if not.
  • functions (Object)[optional]: if specified, enter an object with functions as attributes. You can call these functions by their name from the front-end later. Use object-destructuring for parameters.
app.use(require('express-functions')({
  events: true,
  // example
  functions: {
    add({ num1, num2 }) {
      return num1 + num2;
    }
  }
}));

Frontend Docs

  • exprfn.connect([backend-domain])

Call this function to connect your front-end application with your back-end. This is an async function, so I advise to use it like this:

const backend = await exprfn.connect();

The connect function takes the domain of your back-end server as an optional argument: await exprfn.connect('https://your.domain.com');

It returns an object with the following functions:

  • .call({functionName}, [functionParams])

The call function lets you call functions which you specified in your express-functions configuration on your server. This is an async function. The functionName is a required parameter (string). The functionParams (object) obviously depend on the function you specified on your server.

console.log(backend.call('add', { a: 5, b: 3 })) // => 8
  • .once({eventName})

The once function is used with events. With this you listen for an event with the given eventName (string). This is an async function. The data which the event is triggered with will get resolved once.

// example
backend.once('someDudeLoggedIn')
  .then(data => {
    alert(`User ${data.name} just logged in`);
  })
  • .on({eventName}, {callback});

The on function is used with events. With this you can listen for events beeing fired off multiple times.

// example
backend.on(`message:from:${friend.name}`, (data) => {
  alert(`Message from ${friend.name}: ${data.msg}`);
})
  • .emit({eventName}, [data]);

The emit function will trigger an event on the server. Every request for listening to this eventName (string) will get resolved. The optional data (object) will be passed to the receiver if provided.

// sender
backend.emit(`msg:from:${myToken}:to:${friendsToken}`, { msg: 'Hello' });
// receiver
backend.on(`msg:from:${friendsToken}:to:${myToken}`, (data) => {
  alert(`Message from ${friend.name}: ${data.msg}`);
});