Deploy Tutorial

Deploy a static site to WREN, preview changes before going live, and promote when ready. Takes about 10 minutes.

Prerequisites

  1. 1 A running WREN instance (local Docker or wren.aemwip.com)
  2. 2 The WREN CLI installed: bun install -g @usewren/cli (or run from the repo with bun run cli/index.ts)
  3. 3 An account — sign up via the Admin UI
Configure the CLI. Point it at your server and sign in:
bash
wren config --url https://wren.aemwip.com
wren auth login -e [email protected] -p yourpassword
wren me   # confirm: shows your principal, org, and role

1 Create a simple site

Let’s make a minimal static site to deploy. Create a folder with a few files:

bash
mkdir my-site && cd my-site

cat > index.html <<'EOF'
<!DOCTYPE html>
<html>
<head>
  <title>My WREN Site</title>
  <link rel="stylesheet" href="/assets/style.css">
</head>
<body>
  <h1>Hello from WREN!</h1>
  <p>Deployed with <code>wren deploy</code>.</p>
  <a href="/about.html">About</a>
</body>
</html>
EOF

cat > about.html <<'EOF'
<!DOCTYPE html>
<html>
<head>
  <title>About — My WREN Site</title>
  <link rel="stylesheet" href="/assets/style.css">
</head>
<body>
  <h1>About</h1>
  <p>This site is versioned and served by WREN.</p>
  <a href="/">Home</a>
</body>
</html>
EOF

mkdir -p assets
cat > assets/style.css <<'EOF'
body { font-family: system-ui, sans-serif; max-width: 640px; margin: 2rem auto; padding: 0 1rem; line-height: 1.6; }
h1 { color: #4338ca; }
a { color: #6366f1; }
EOF

You now have index.html, about.html, and assets/style.css.


2 First deploy

Deploy the folder to a WREN tree. The --public flag creates a permission rule so anyone can view the site.

bash
wren deploy . --tree my-site --public

Output:

output
Found 3 files in .
Creating binary collection: my-site-assets
  Uploaded 3 files...
Created public read permission for tree:my-site

Deployed to tree "my-site":  3 uploaded, 0 unchanged, 3 new paths

Preview:  https://wren.aemwip.com/orgs/your-slug/tree/my-site/index.html
What just happened:
  1. A binary collection my-site-assets was created to store your files
  2. Each file was uploaded as a versioned binary document
  3. Each file was assigned to a tree path matching its local path
  4. A principal=* read permission was added so the site is public

3 See it live

Open the URL from the output in your browser. Your site is live — HTML, CSS, and all. Links between pages work because tree paths match your directory structure.

You can also check it from the CLI:

bash
wren tree view my-site
output
  /about.html       [my-site-assets v1]  size: 234
  /assets/style.css [my-site-assets v1]  size: 168
  /index.html       [my-site-assets v1]  size: 265

Every file is at version 1. The tree serves them at their local paths.


4 Make a change

Edit index.html — change the heading:

html
<h1>Hello from WREN! — Updated</h1>
<p>This is version 2 of the site.</p>

Re-deploy. Only the changed file uploads:

bash
wren deploy . --tree my-site
output
Found 3 files in .

Deployed to tree "my-site":  1 uploaded, 2 unchanged, 0 new paths

WREN detected that about.html and style.css haven’t changed (same file size) and skipped them. Only index.html was uploaded as version 2.


5 Deploy as preview

What if you want to test changes before the public sees them? Deploy with a label:

bash
# Make another change
sed -i '' 's/Updated/v3 Preview/' index.html

# Deploy with --label preview
wren deploy . --tree my-site --label preview

The public site is unchanged — visitors still see the current version. You can see the preview by adding ?label=preview to any URL:

bash
# Public site (unchanged):
open https://wren.aemwip.com/orgs/your-slug/tree/my-site/index.html

# Your preview (new version):
open https://wren.aemwip.com/orgs/your-slug/tree/my-site/index.html?label=preview
How labels control visibility: If you created a permission with labelFilter: "published", anonymous visitors would only see the published label. The --public flag on the first deploy didn’t set a labelFilter, so visitors currently see the latest version. To enable preview → publish flow, set a labelFilter on the permission rule via the Admin UI or the API.

6 Promote to published

Happy with the preview? Promote it:

bash
wren promote my-site --from preview
output
Promoting 3 documents in tree "my-site" → label "published" (from "preview")...
Done: 3 documents labeled "published".

Public: https://wren.aemwip.com/orgs/your-slug/tree/my-site/index.html?label=published

The published label now points to the same versions as preview. If your permission has labelFilter: "published", the public site is updated.

You can also promote without a source label — this labels the current (latest) version of every document in the tree:

bash
wren promote my-site   # defaults to --label published

7 Add JSON data alongside your site

WREN isn’t just file hosting. Your site can read structured data from a collection via the API:

bash
# Create a JSON collection for your site's content
wren create pages '{"slug":"home","title":"Welcome","body":"This content is stored in WREN."}'
wren create pages '{"slug":"about","title":"About Us","body":"We are a team building with WREN."}'

# Your site's JavaScript can fetch from the public API:
# GET /api/v1/orgs/your-slug/pages

Now your static site and its content data live in the same system. When you promote, both the HTML files and the JSON content can move to published together.

The easiest way to display this data in your HTML is wren.js — a one-line script that gives you web components for data binding:

html
<!-- Add to your index.html -->
<script src="/wren.js"></script>

<!-- List pages from the collection -->
<wren-list collection="pages" select="title,body">
  <template>
    <article>
      <h2>{{title}}</h2>
      <p>{{body}}</p>
    </article>
  </template>
</wren-list>

<!-- Or fetch a single page by its slug -->
<wren-doc collection="pages" key="about">
  <template>
    <h1>{{title}}</h1>
    <p>{{body}}</p>
  </template>
</wren-doc>

No JavaScript to write — the components auto-detect the org from the URL, fetch the data, and render the template. See the full wren.js tutorial for aggregation, materialized views, custom domains, and more.


8 Rollback

Every file upload creates a new version. You can roll back any individual file:

bash
# See version history for a document
wren versions my-site-assets <document-id>

# Roll back to version 1
wren rollback my-site-assets <document-id> 1

# Re-promote to make the rollback live
wren promote my-site

Or roll back the entire site by promoting an older label. If you labeled yesterday’s deploy as v1, just re-promote it:

bash
wren promote my-site --from v1 --label published

9 Cleanup: remove deleted files

If you delete a file locally and redeploy, the old tree path stays by default. Use --clean to remove paths that no longer exist in your local directory:

bash
rm about.html
wren deploy . --tree my-site --clean
output
Found 2 files in .

Deployed to tree "my-site":  0 uploaded, 2 unchanged, 0 new paths, 1 removed

/about.html is removed from the tree. The document still exists in the collection (soft-deleted or just unassigned) — nothing is permanently lost.


What’s next

  • Full WREN tutorial — covers the Admin UI, collections, schemas, labels, permissions, and more
  • API Docs — interactive reference for every endpoint
  • Projects — see live sites deployed on this WREN instance
  • Admin UI — browse your deployed files, manage permissions, and edit content
Quick reference:
wren deploy ./dist --tree mysite --public       # first deploy
wren deploy ./dist --tree mysite --label preview # preview deploy
wren promote mysite --from preview               # go live
wren promote mysite                              # label current as published
wren deploy ./dist --tree mysite --clean          # remove deleted files
wren tree view mysite                            # inspect the tree