What is Membrane?

Stateful serverless TypeScript for internal tools.

FEATURES
EXAMPLES
example hn follow
Uses the hn Driver to "follow" users on Hacker News and get notifications (email or SMS) when they post something new.
Set up a "cron-job" timer that invokes check periodically.
Store "last seen" in state for persistence.
Send yourself an text message
import { nodes, root, state } from "membrane";
const { hn, sms } = nodes;

export function setup() {
  root.check.$cron("30 35 * * * *");
}

export async function follow({ username }) {
  const { id, submitted } = await hn.users
    .one({ id: username })
    .$query(`{ id submitted { items { id } } }`);
  const lastSeen = submitted?.items?.[0]?.id ?? 0;
  state[username] = { id, lastSeen };
}

export async function check() {
  for (const [username, { lastSeen }] of Object.entries(state)) {
    const items = await hn.users
      .one({ id: username })
      .submitted.items.$query(`{ id }`);

    const latest = (items ?? [])[0];
    if (latest?.id! > (lastSeen as number)) {
      const url = `https://news.ycombinator.com/item?id=${latest.id}`;
      await sms.send({ message: `New HN post from ${username}: ${url}` })
      state[username] = latest.id!;
    }
  }
}

What is Membrane?

Stateful serverless TypeScript for internal tools.

FEATURES
EXAMPLES
Uses the hn Driver to "follow" users on Hacker News and get notifications (email or SMS) when they post something new.
Set up a "cron-job" timer that invokes check periodically.
Store "last seen" in state for persistence.
Send yourself an text message
import { nodes, root, state } from "membrane";
const { hn, sms } = nodes;

export function setup() {
  root.check.$cron("30 35 * * * *");
}

export async function follow({ username }) {
  const { id, submitted } = await hn.users
    .one({ id: username })
    .$query(`{ id submitted { items { id } } }`);
  const lastSeen = submitted?.items?.[0]?.id ?? 0;
  state[username] = { id, lastSeen };
}

export async function check() {
  for (const [username, { lastSeen }] of Object.entries(state)) {
    const items = await hn.users
      .one({ id: username })
      .submitted.items.$query(`{ id }`);

    const latest = (items ?? [])[0];
    if (latest?.id! > (lastSeen as number)) {
      const url = `https://news.ycombinator.com/item?id=${latest.id}`;
      await sms.send({ message: `New HN post from ${username}: ${url}` })
      state[username] = latest.id!;
    }
  }
}
Features Walkthrough
In this video we discuss 3 of the most important features of Membrane: Durability, The Graph, and Observability.
Clickable poster of the Features Walkthrough video

If you're curious about Membrane's architecture, Juan joined the devtools.fm podcast to talk through the nuts and bolts.

Communication


Enter your email for occasional updates