Deploy a Walrus Site
The Walrus Sites site-builder uploads your website's files to Walrus, where resources like HTML, CSS, JavaScript, and images are stored as blobs. A Sui smart contract serves as an onchain index that maps each resource path to its Walrus blob ID and records site ownership. Portals read this onchain index to resolve and serve your site in the browser to visitors.
To create a Walrus Site, your website's source files must include an index.html at the root to serve as the entry point. For example, the walrus-snake site has the following assets:
walrus-snake/
├── file.svg
├── index.html
├── Oi-Regular.ttf
├── walrus.svg
└── ws-resources.json
You can find additional examples in the Walrus Sites example repository.
- Prerequisites
These prerequisite setup guides install Walrus, the site-builder tool, and their configuration files to the default directories. If you installed Walrus or the site-builder tool using other guides or resources, your installation locations might be different.
If your site-builder configuration file is in a different location, use the --config flag to specify the path.
Deploy an example site
To demonstrate publishing and updating a Walrus Site, clone and deploy the walrus-snake game from the Walrus Sites example repository.
First, clone the example repository:
$ git clone https://github.com/MystenLabs/example-walrus-sites.git && cd example-walrus-sites
Then, deploy the website:
$ site-builder --context=testnet deploy ./walrus-snake --epochs 1
On Walrus Testnet, the duration of an epoch is 1 day, meaning this site will only be available for up to 24 hours. To make it available for longer, specify a larger number of epochs using the --epochs flag.
View your deployed site
How you access your site depends on the network you deploy to:
-
Testnet sites: Can be accessed through a self-hosted or locally deployed portal. There are no public Testnet portals.
-
Mainnet sites: Can be accessed through the Mainnet portal
https://wal.appoperated by Mysten Labs . However, to access your Walrus Site through https://wal.app, a SuiNS name is required. You will not be able to view your Mainnet site until a SuiNS name is configured for it.
The console output at the end of a successful Walrus Sites deployment should look like the following:
Execution completed
Resource operations performed:
- created resource /Oi-Regular.ttf with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBHgAjAg
- created resource /file.svg with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBAQAMAA
- created resource /index.html with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBDAAZAA
- created resource /walrus.svg with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBGQAeAA
The site routes were modified.
Metadata updated.
The site name has been updated.
Created new site!
New site object ID: 0x617221edd060dafb4070b73160ebf535e1516bf7f246890ed35190eba786d7ac
⚠ wal.app only supports sites deployed on mainnet.
To browse your testnet site, you need to self-host a portal:
1. For local development: http://2ffmxm7jmglccr79htmpdbaeqezp2krgftue5pfq9f83tdqjsc.localhost:3000
2. For public sharing: http://2ffmxm7jmglccr79htmpdbaeqezp2krgftue5pfq9f83tdqjsc.yourdomain.com:3000
📖 Setup instructions: https://docs.wal.app/docs/sites/portals/deploy-locally.html#running-the-portal-locally
💡 Tip: You may also bring your own domain (/docs/sites/custom-domains/bringing-your-own-domain)
or find third-party hosted testnet portals.
This output shows the following:
- For each file in your website's build directory, a new blob is created and uploaded to Walrus. Walrus Sites uses the Walrus Quilt feature to optimize storage of small website files. This means every blob created as part of a Walrus Site has a
QuiltPatchID. Together, these form a single quilt. This is because thesite-builderstores files on Walrus using quilts, which offers faster upload speeds and lower storage costs, especially when uploading many small files. The tradeoff is that you cannot update a single file within a quilt; if any file changes, the entire quilt must be re-uploaded. - A Walrus Site object is created on Sui. Use the printed object ID to view the site's object information through a network explorer. This site object is what you will link to a SuiNS name for sites deployed to Mainnet. The
deploycommand saves the site object ID to the local filews-resources.json. - The URL where you can browse the site.
Update the site
When a site is updated, all site resources are deleted and re-uploaded together as a single quilt, even resources that have not changed.
To update the example walrus-snake site, like changing the title from "eat all the blobs!" to "Glob all the Blobs!", make the edit in the ./walrus-snake/index.html file.
You can then update the existing site by running the deploy command again:
$ site-builder --context=testnet deploy --epochs 1 ./walrus-snake
The deploy command uses the site object ID stored in ws-resources.json from the initial deployment to identify which site to update. If you want to update a different site than the one in ws-resources, you can specify a different object ID using the --object-id <OBJECT_ID> flag.
$ site-builder --context=testnet deploy --object-id 0x617221edd060dafb4070b73160ebf535e1516bf7f246890ed35190eba786d7ac --epochs 1 ./walrus-snake
Additionally, the wallet you are using must be the owner of the Walrus Site object to be able to update it.
The output this time should be:
Execution completed
Resource operations performed:
- deleted resource /Oi-Regular.ttf with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBHgAjAg
- deleted resource /file.svg with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBAQAMAA
- deleted resource /index.html with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBDAAZAA
- deleted resource /walrus.svg with quilt patch ID Jqz2KSMu18pygjkC-WVEQqtUZRo18-cuf_566VZSxVoBGQAeAA
- created resource /Oi-Regular.ttf with quilt patch ID BjJAfHLJKMDZ0tFZaLKVw0R74re5RG65-xNhaZ5uwowBHgAjAg
- created resource /file.svg with quilt patch ID BjJAfHLJKMDZ0tFZaLKVw0R74re5RG65-xNhaZ5uwowBAQAMAA
- created resource /index.html with quilt patch ID BjJAfHLJKMDZ0tFZaLKVw0R74re5RG65-xNhaZ5uwowBDAAZAA
- created resource /walrus.svg with quilt patch ID BjJAfHLJKMDZ0tFZaLKVw0R74re5RG65-xNhaZ5uwowBGQAeAA
The site routes were left unchanged.
No Metadata updated.
Site name has not been updated.
Site object ID: 0x4a1be0fb330215c532d74c70d34bc35f185cc7ce025e04b9ad42bc4ac8eda5ce
⚠ wal.app only supports sites deployed on mainnet.
To browse your testnet site, you need to self-host a portal:
1. For local development: http://1uhtkoi4t8swxbn2y0mec0l94368nhq2wa1xlh1kc1e43fbzym.localhost:3000
2. For public sharing: http://1uhtkoi4t8swxbn2y0mec0l94368nhq2wa1xlh1kc1e43fbzym.yourdomain.com:3000
📖 Setup instructions: https://docs.wal.app/walrus-sites/portal.html#running-the-portal-locally
💡 Tip: You may also bring your own domain (/docs/sites/custom-domains/bringing-your-own-domain)
or find third-party hosted testnet portals.
Using a web framework
If you are building a Walrus Site using a web framework (such as React, Node.js, or Django), ensure
you point the site-builder to your site's build output folder when running the deploy
command. site-builder should not point to the project root.
When you use site-builder deploy, every file in the directory you point it to is uploaded. Uploading
your project root would include directories like node_modules/, which can contain tens of
thousands of files and hundreds of megabytes of dependencies. This results in:
- Significantly longer upload times as every file is processed and stored.
- Higher storage costs, since you pay for every byte stored on Walrus.
- Unnecessary files on your site. Source files, config, and dependencies are not needed to serve your site to visitors.
Your build output folder contains only the compiled, optimized assets that browsers actually need like HTML, CSS, JavaScript bundles, and static assets.
Example: Vite project
A typical Vite project structure looks like this before building:
my-website/
├── node_modules/ # dependencies: never deploy this
├── public/ # static assets
├── src/ # source files: never deploy this
├── index.html
├── package.json
├── vite.config.js
└── .gitignore
Running npm run build generates a dist/ folder containing only the files needed to serve your
site:
my-website/
├── dist/ # deploy this folder only
│ ├── assets/
│ └── index.html
├── node_modules/ # never deploy this
├── public/
├── src/ # never deploy this
├── index.html
├── package.json
├── vite.config.js
└── .gitignore
Build folder names vary by framework Different frameworks use different names for their build output:
| Framework | Output folder |
|---|---|
| Vite | dist/ |
| Create React App | build/ |
| Next.js | out/ |
| Vue CLI | dist/ |
| Docusaurus | build/ |
Always check your framework's documentation to confirm the correct output folder.
Once your site is built, deploy using the site-builder pointed at the output folder:
$ site-builder --context=testnet deploy --epochs 1 my-website/dist
Redirects
Walrus Sites does not support dynamic redirects. Unlike traditional web servers or hosting platforms that can intercept requests and resolve routes at runtime, Walrus Sites serves static files directly. There is no server-side logic to handle URL resolution.
This means that redirect plugins do not work on Walrus Sites. For example, if you are using Docusaurus, the redirect plugin that routes /file/path/old to /file/path/new will not function as expected when deployed to Walrus Sites.
There are workarounds for simulating redirect behavior in the browser. For more information, see the routing documentation.
Exporting markdown
If you have a script that generates pure markdown files from your site's pages for ingestion by agents, you must configure ws-resources.json to serve those files correctly. Two things are required: a header entry and a route entry.
Headers
Add a header entry in your ws-resources.json file for each markdown file so that browsers and tools receive the correct Content-Type and display the file inline rather than triggering a download:
{
"headers": {
"/markdown/walrus-sites/tutorial.md": {
"Content-Disposition": "inline",
"content-type": "text/markdown; charset=utf-8"
}
}
}
This entry is case sensitive. "content-type" must be lowercase.
Without this, the file will be served as a generic binary download rather than readable markdown.
Routes
Add a route entry mapping the public-facing URL to the markdown file's path in your build output:
{
"routes": {
"/docs/examples/checkpoint-data.md": "/markdown/examples/checkpoint-data.md"
}
}
The key is the URL path a visitor or tool requests, and the value is the location of the markdown file in your deployed build.
Combined example
A complete ws-resources.json with both entries for a markdown file looks like this:
{
"headers": {
"/markdown/examples/checkpoint-data.md": {
"Content-Disposition": "inline",
"content-type": "text/markdown; charset=utf-8"
}
},
"routes": {
"/docs/examples/checkpoint-data.md": "/markdown/examples/checkpoint-data.md"
}
}
For more information, see the routing documentation and the headers documentation.
To update your Walrus Site, ensure you rebuild your website first before running deploy again.