Skip to content

Introduction

What is Freestyle?

Freestyle is a TypeScript framework and runtime for building applications that leans into the TypeScript language to provide a more expressive and powerful way to build applications.

Under the hood, Freestyle has two parts: a runtime and a compiler. The compiler takes your regular TypeScript code and transforms it into a format that the runtime can understand. The runtime allows us to make your in-memory TypeScript code persistent without needing to write any non-TypeScript code.

Main Features

FeatureDescription
Cloudstate DatabaseBy adding @cloudstate, before any class, you can make the data in it persistent. No SQL, no Prisma, just TypeScript for querying, accessing and storing the data
Cloudstate StorageInstead of a separate S3 offering, take any blob, store it on a @cloudstate class, and it will be persisted there
useCloudCall any function on a @cloudstate class from the frontend, and it will be executed on the backend. Full strong types with 0 configuration
useCloudQueryYou can make any function on a cloudstate class automatically sync to changes from the backend by wrapping it in useCloudQuery and calling invalidate on the underlying functions on the backend.

Manifesto

In 2009, JavaScript came to the server with Node.js. Since then, a ton of tooling has evolved for frontend and backend with JavaScript, however none of it has really acknowledged that the frontend and backend are both TypeScript.

For example, NextJS API Routes are almost exclusively consumed by JavaScript frontends, yet you’re forced to Serialize to a Response object in them making their functions non-reusable on the backend.

We believe the barriers to stability, collaboration, and productivity in fullstack TypeScript are the parts that exist outside of TypeScript.

We believe that the benefits of building in TypeScript come from the ability to have a whole app work together in a single codebase, and we built Freestyle to push that idea to its limits.

We believe the best query language possible for TypeScript projects is TypeScript. Before Freestyle, when you wanted to build anything with persistent data, you had to structure your app around the database. We believe that the database should be structured around your app, so we made it so to query the database, you just write TypeScript, and to store data, you just write TypeScript. No ORM, no .commit(), just regular TypeScript. 1 line of non-standard TypeScript code: @cloudstate.

// like this
@cloudstate
export class SimpleCounter {
static id = "simple-counter";
count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
getCount() {
return this.count;
}
}

REST, GraphQL, and any other RPC you can think of are a way to call functions from your backend on your frontend. In the context of fullstack TypeScript, that means calling a TypeScript function from your TypeScript frontend on your TypeScript backend. So, we let you call the functions on any class marked @cloudstate from your backend on your frontend. Full strong types, 1 line of non-standard TypeScript code: useCloud.

export function Counter() {
const counter = useCloud("simple-counter");
let count = undefined;
useEffect(async () => {
// backend function, from your frontend
count = await counter.getCount();
}, []);
return (
<div>
<button onClick={counter.increment}>Increment</button>
<button onClick={counter.decrement}>Decrement</button>
<div>{count}</div>
</div>
);
}

We believe Blobs are just another kind of data, and storing / moving them should be the same as moving string. So, we made it so that you can store any blob on a @cloudstate class, and it will be persisted there. No S3, no fs.writeFile, just TypeScript. 1 line of non-standard TypeScript code: @cloudstate.

@cloudstate
export class Image {
id = crypto.randomUUID();
blob: Blob
constructor(blob: Blob) {
this.blob = blob;
}
}

These are the core ideas that drive Freestyle. We are committed to empowering TypeScript developers to build with TypeScript