Skip to main content

Functions

Functions are a set of features enabling developers to extend the native capabilities of Satellites using Rust or TypeScript. They let you define serverless behaviors directly within your containerized environment.

There are two types of functions:

  • Event-driven functions: triggered automatically in response to actions such as a document being created or an asset being uploaded.
  • Callable functions: explicitly invoked from your frontend or from other services.

Event-driven Functions

Event-driven functions respond to actions occurring in your Satellite. They are triggered automatically and never invoked directly.

Hooks

Hooks respond to specific actions within your Satellite. They run asynchronously, independently of the caller's request - meaning the caller may receive a response before the hook has finished executing.

Functions hooks flow

note

Hooks are only initiated when the preceding operation completes without errors.

HookProviderDescription
on_set_docDatastoreTriggered when a document is created or updated.
on_set_many_docsDatastoreActivated for operations involving multiple documents.
on_delete_docDatastoreInvoked when a document is deleted.
on_delete_many_docsDatastoreUsed when multiple documents are deleted.
on_delete_filtered_docsDatastoreInvoked when documents are deleted according filters.
on_upload_assetStorageTriggered during asset upload.
on_delete_assetStorageActivated when an asset is deleted.
on_delete_many_assetsStorageUsed for deleting multiple assets.
on_delete_filtered_assetsStorageInvoked when assets are deleted based on filters.
on_initSatelliteCalled during the initialization of the Satellite.
on_post_upgradeSatelliteInvoked after the Satellite has been upgraded to a new version.

Assertions

Assertions run synchronously before an operation is executed. They allow you to validate or reject actions before any data is written.

AssertionProviderDescription
assert_set_docDatastoreEnsures a document can be created or updated.
assert_delete_docDatastoreVerifies that a document can be deleted.
assert_upload_assetStorageConfirms an asset upload can be committed.
assert_delete_assetStorageChecks that an asset can be deleted.

Callable Functions

Callable functions are explicitly invoked — from your frontend or from other services. They expose query and update endpoints directly from your Satellite.

tip

This is conceptually similar to exposing your own endpoints on an API.

TypeDescription
queryA read-only function that returns data without modifying state.
updateA function that can read and write state.

Rust vs. TypeScript

You can write serverless functions in either Rust or TypeScript, depending on your needs and project goals.

Rust will always be more performant than TypeScript because TypeScript code is evaluated by the Rust runtime under the hood. This means that, no matter how optimized, functions written in Rust will consume fewer cycles and execute faster. That said, not every project needs maximum performance from day one. For smaller apps, rapid prototypes, or internal tools, TypeScript can be a perfect fit.

The Rust ecosystem is also more mature, having been supported on the Internet Computer from the beginning. It benefits from better compatibility with libraries that support wasm32-unknown-unknown.

TypeScript support was introduced on Juno in April 2025. While developer-friendly, it currently lacks Node.js polyfills, which means many npm libraries may not work out of the box. That said, we’re actively improving this — and if there's a specific package or feature you'd like to use, reach out. We're happy to explore adding support.

It is worth to note that in both environments, there is no standard library or file system access. Functions like reading from or writing to disk aren’t available. Instead, e.g. Juno provides purpose-built features such as Storage.

Despite their differences, Rust and TypeScript serverless functions are designed with interoperability in mind. The API surface and structure are intentionally aligned, so migrating from TypeScript to Rust later should feel intuitive and straightforward.

Summary

Feature / ConsiderationRustTypeScript
Performance✅ Highest, runs natively in WASM⚠️ Interpreted by Rust, slower
Library Support✅ Many crates⚠️ Limited (only few Node.js polyfills currently supported)
Ease of Use✅ Developer-friendly (with or without AI)✅ Developer-friendly (with or without AI)
Migration Path✅ Can migrate to Rust easily
Recommended ForProduction apps, performance-critical codePrototypes, smaller tools, quick dev cycles