Configuration
All available options for serverless deployments.
When deploying to Freestyle, there are two distinct parameter groups:
- Source: Where your code comes from—a Git repository, raw files, or a tarball link.
- Options: Settings like domains, build configuration, entrypoint, timeout, and more.
Deployment Source
There are 3 types of sources you can use to deploy:
Git
A Git repository containing your code. This can be a public repository, a repository with basic authentication in the URL, or any repository in your account on Freestyle Git. This is the most common and recommended approach because it provides observability and debuggability.
import { freestyle } from "freestyle";
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
branch: "main", // optional, defaults to default branch
rootPath: "./web", // optional, defaults to root
domains: ["app.style.dev"],
build: true,
});Code
A code snippet to deploy directly. Useful for simple deployments or rapid iteration.
import { freestyle } from "freestyle";
await freestyle.serverless.deployments.create({
code: `
import express from 'express';
const app = express();
app.get('/', (req, res) => res.send('Hello World'));
app.listen(3000);
`,
nodeModules: {
express: "^4.18.2",
},
domains: ["api.style.dev"],
});Tar Link
A link to a gzipped tarball containing your files. This is useful when your main app is hosted on a serverless platform with request size limits. Instead of uploading files directly, your users upload to a storage service (like S3) and provide a signed link.
import { freestyle } from "freestyle";
await freestyle.serverless.deployments.create({
tarUrl: "https://s3.example.com/signed-url/app.tar.gz",
domains: ["app.style.dev"],
build: true,
});When deploying to Freestyle you never upload node_modules. Include your
package-lock.json, yarn.lock, pnpm-lock.yaml, or bun.lock file in
your source. Freestyle automatically installs dependencies, keeping
deployments small and fast.
Deployment Options
Domains
Specify which domains to deploy to. You can use any *.style.dev subdomain that isn't taken, or any verified custom domain.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
domains: ["app.style.dev", "app.yourdomain.com"],
});Entrypoint
The main file of your application. By default, Freestyle automatically detects the entrypoint for frameworks like Next.js, Vite, and Expo. For custom setups, specify it manually.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
entrypoint: "server.js",
domains: ["app.style.dev"],
});Node Modules
By default, Freestyle installs dependencies from your lockfile. You can also specify additional packages directly.
await freestyle.serverless.deployments.create({
code: `import express from 'express'; /* ... */`,
nodeModules: {
express: "^4.18.2",
cors: "^2.8.5",
},
domains: ["api.style.dev"],
});Environment Variables
Environment variables available at runtime. These are not available at build time—use build options for that. Environment variables are tied to deployments; to change them, create a new deployment.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
envVars: {
API_KEY: "your-api-key",
DATABASE_URL: "postgres://...",
},
domains: ["app.style.dev"],
});Timeout
The maximum idle time before your deployment is scaled down. Unlike most serverless platforms that timeout after the last request, Freestyle timeouts after the last TCP packet. This means websockets can stay alive indefinitely as long as you ping faster than the timeout.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
timeoutMs: 60000, // milliseconds
domains: ["app.style.dev"],
});Build
By default, Freestyle deploys files as-is. Set build: true to have Freestyle build your code. It automatically detects frameworks like Next.js, Vite, and Expo.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
build: true,
domains: ["app.style.dev"],
});For more control, pass build options:
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
build: {
command: "npm run build", // custom build command
outDir: "dist", // output directory
envVars: { // build-time environment variables
NEXT_PUBLIC_API_URL: "https://api.example.com",
},
},
domains: ["app.style.dev"],
});Await
By default, the deployment request waits until the deployment is built and propagated before returning. Set await: false to return immediately with a deployment ID for polling.
const { deploymentId } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
await: false,
domains: ["app.style.dev"],
});
// Poll for status
const status = await freestyle.serverless.deployments.get({ deploymentId });Static File Hosting
Static Only
Deploy a pure static site without any server. When enabled, no entrypoint is required and Freestyle serves files directly.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-site",
staticOnly: true,
publicDir: "public",
domains: ["site.style.dev"],
});Public Dir
Directory containing files to serve at your domain root. A file at public/favicon.ico is served at /favicon.ico.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-site",
publicDir: "public",
staticOnly: true,
domains: ["site.style.dev"],
});Static Dir and Static Path Prefix
Serve a specific directory at a specific URL path prefix. Useful for framework-specific assets like Next.js's .next/static.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-app",
staticDir: ".next/static",
staticPathPrefix: "/_next/static",
staticOnly: true,
domains: ["app.style.dev"],
});Files in .next/static/ are served at /_next/static/...
Prerendered Dir
Directory containing prerendered HTML files that map to URL paths. Perfect for static site generators.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-site",
prerenderedDir: "out",
staticOnly: true,
domains: ["site.style.dev"],
});Requests are mapped as follows:
/about→out/about.html/→out/index.html/blog/post→out/blog/post.html
Clean URLs
Remove .html extensions from URLs. When enabled, requests for /about.html redirect to /about and serve the HTML file.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-site",
publicDir: "public",
cleanUrls: true,
staticOnly: true,
domains: ["site.style.dev"],
});Trailing Slash
Control trailing slash behavior. When true, trailing slashes are preserved. When false, they trigger redirects.
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-site",
publicDir: "public",
trailingSlash: true, // /about/ is served, /about redirects to /about/
staticOnly: true,
domains: ["site.style.dev"],
});Combined Example
All options can be combined:
import { freestyle } from "freestyle";
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-repo",
branch: "production",
rootPath: "./apps/web",
domains: ["app.yourdomain.com", "app.style.dev"],
entrypoint: "server.js",
timeout: 120,
envVars: {
API_KEY: "runtime-secret",
},
build: {
command: "npm run build",
outDir: "dist",
envVars: {
NEXT_PUBLIC_API_URL: "https://api.example.com",
},
},
});Static Site Example
Combine static file hosting options for a complete static site deployment:
import { freestyle } from "freestyle";
await freestyle.serverless.deployments.create({
repo: "https://github.com/your-org/your-static-site",
branch: "main",
domains: ["site.yourdomain.com", "site.style.dev"],
staticOnly: true,
publicDir: "public",
cleanUrls: true,
trailingSlash: false,
build: {
command: "npm run build",
outDir: "public",
},
});