// CreateTodo.telefunc.js
// Environment: Node.js server

import { shield, Abort, getContext } from 'telefunc'

// Telefunc makes functions exported in `*.telefunc.js`
// remotely callable from the browser.
export { onNewTodo }

shield(onNewTodo, [{ text: shield.type.string }])
async function onNewTodo({ text }) {
  const { user } = getContext()
  if (user === null) throw Abort()

  // With an ORM:
  const todoItem = new Todo({text, authorId: user.id})
  await todoItem.save()

  // Or with SQL:
  await execute(
    "INSERT INTO todo_items VALUES (:text, :authorId)",
    { text, authorId: user.id }
// CreateTodo.jsx
// Environment: Browser

// The `CreateTodo.telefunc.js` file is not loaded:
// Telefunc transforms `*.telefunc.js` imports into a
// thin HTTP client.
import { onNewTodo } from './CreateTodo.telefunc.js'

async function onClick(form) {
  const text = form.input.value
  // Behind the scenes, Telefunc makes an HTTP request
  await onNewTodo(text)

function CreateTodo() {
  return (
      <input input="text"></input>
      <button onClick={onClick}>Add To-Do</button>

💫 Simple

Telefunc simplifies the frontend-backend relationship — with Telefunc it's just a set of remote functions.

Your frontend can directly use any SQL/ORM query to retrieve & mutate data.


Telefunc enables programmatically defined permissions.

It's both simple and flexible.

🔌 Any Stack

Telefunc supports Webpack and Vite based frameworks: Next.js, Nuxt, Vite, Vike, SvelteKit, Angular, CRA, Gatsby, etc.

You want to change your stack? Bring Telefunc along.


The frontend can directly tap into the full power of the server. Highly tailored & optimized SQL/ORM queries can be used for highly-performant data retrieval & mutations.


Seamless TypeScript support out-of-the-box.

Use your types across frontend-backend for end-to-end type safety.

💎 Rock-solid

The source code of Telefunc has no known bug (bugs are fixed swiftly) and every release is assailed against a heavy suite of automated tests.

Have a question? Want a feature? Found a bug? Join our Discord or open a GitHub ticket.