Client scripts
Code inside cs`…`, written in your server's files and run on the phone.
import { type Client, cs } from "@backtickjs/core";import { Text, View } from "@backtickjs/react-native";// An expression: a value the phone computes, with the phone's own clock.const greeting: Client<string> = cs`new Date().getHours() < 12? "Good morning": "Good afternoon"`;// A function the phone calls.const formatPrice: Client<(price: number) => string> = cs`(price: number) =>price.toLocaleString("en-US", { style: "currency", currency: "USD" })`;export async function Home() {const total = 13.5;// Statements, ending in what the script is: here, the screen.return cs`{const label = $formatPrice($total);return (<$View style={{ padding: 24, gap: 8 }}><$Text>{$greeting}</$Text><$Text>Your total is {label}.</$Text></$View>);}`;}
A client script is code inside cs`…`. It's written in your server's
files, but it runs on the phone. To your server, a script is a value, a
Client<T>: something the phone will compute as a T.
Three shapes
A script is an expression, a block of statements, or a function:
- An expression, like
greeting:cs`new Date().getHours() < 12 ? …`. It's aClient<string>, computed on the phone, so it reads the phone's clock rather than your server's. - A block of statements, like the script
Homereturns:cs`{ … }`. Itsreturnis what it is, here the screen. Use it when the script needs variables of its own. - A function, like
formatPrice:cs`(price: number) => …`. It's aClient<(price: number) => string>, a function the phone calls. A function that returns JSX is a client component.
TypeScript infers each type, as Client<string> here; the annotations in the
example only show them.
Full JavaScript
A script is ordinary modern JavaScript and TypeScript: loops, try/catch,
async functions, classes, destructuring, and JSX. It runs on the phone with
the phone's globals: fetch, setTimeout, JSON, Math, Intl, console
and the rest.
What a script can see
A script sees its own code and the phone's globals, but not the file around
it: that's your server's code. To use a value from your server, splice it with
$, as $total and $formatPrice do. Forget the $, and TypeScript looks
for a global by that name:
import { cs } from "@backtickjs/core";import { Text } from "@backtickjs/react-native";export async function Home() {const total = 13.5;return cs`(// @ts-expect-error: Property 'total' does not exist on type 'GlobalThis'.<$Text>Your total is {total}.</$Text>)`;}
Property 'total' does not exist on type 'GlobalThis'.
Splices covers what can cross, and how.
Compiled with your server
Scripts are compiled when your server loads its files, by
@backtickjs/node-plugin on Node or @backtickjs/bun-plugin on Bun, which a
new project already runs. Type errors in a script show in your editor and in
npm run typecheck; see Type checking.