Launch Your Website on ICP

Launch Your Website on ICP

I launched this very website on the Internet Computer using Claude Code and the ICP CLI, and I turned that real workflow into the step-by-step guide below so you can do the same thing. This is a practical Claude Code + ICP CLI guide for beginners: from no Ubuntu setup to a deployed website on the Internet Computer, with a custom domain workflow you can reuse for your own project.

Who this is for: creators, founders, coaches, communities, small businesses, and builders who want to put a real website on ICP without manually coding every file. What you will build: a static website generated and edited with Claude Code, configured with icp.yaml, deployed with the icp command, and optionally mapped to your domain. One important promise up front: this guide uses ICP CLI commands only — it is written for practical deployment, not theory. Use it as a template and replace the example domain example.com, project name my-icp-site, and canister name frontend with your own values.

The 10-step roadmap

You do not need to understand every part before starting. Work through the steps in order and let Claude Code help you generate, edit, and troubleshoot the project files.

StepWhat you do
1. Install UbuntuUse WSL on Windows, or use your normal terminal on Mac/Linux.
2. Install Node.js + basicsInstall Git, build tools, curl, and a current Node.js LTS.
3. Install Claude CodeRun Claude Code in your project folder and use it as your coding partner.
4. Install ICP CLIInstall the icp command and its companion tool with npm.
5. Create the websiteUse Claude Code to create the HTML/CSS/JS or Vite project.
6. Add ICP configCreate icp.yaml and .ic-assets.json5 for the asset canister.
7. Test locallyBuild the site and deploy to a local ICP network.
8. Deploy to ICPDeploy the frontend canister to mainnet with ICP CLI.
9. Add your domainAdd DNS records, deploy /.well-known/ic-domains, and register the domain.
10. Update safelyMake edits, build, deploy or sync, and keep backups.

The fastest path is a static or static-generated website. Add backend canisters later only when you need logins, payments, user data, or dynamic application logic.

Step 1: Install Ubuntu on Windows

If you are on Windows, use Windows Subsystem for Linux so your development environment behaves like a Linux server. Microsoft documents installing WSL with the wsl --install command; new installs default to WSL 2. Mac and Linux users can skip this step and use Terminal.

Run this in PowerShell as Administrator:

wsl --install -d Ubuntu

# After install, restart if Windows asks you to.
# Then open Ubuntu from the Start menu and create your Linux username/password.

Confirm WSL is working:

wsl --list --verbose

Inside Ubuntu, update packages and install basic tools:

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git build-essential ca-certificates unzip

Good habits from the beginning:

  • Keep website projects in your Linux home folder, for example ~/icp-sites.
  • Avoid spaces in project folder names. Use names like my-icp-site.
  • Use Git so you can undo mistakes Claude Code or you make.
  • Do not paste seed phrases, private keys, or account recovery phrases into Claude Code.

Step 2: Install Node.js and Claude Code

Claude Code and ICP CLI both use npm-based installation paths. Claude Code's npm install requires Node.js 18 or later, while the current ICP quickstart recommends Node.js LTS v22+. Use a current LTS version when possible.

Install Node.js and npm:

sudo apt install -y nodejs npm
node --version
npm --version

If your Node version is below the required version, install a newer LTS version before continuing. Ask Claude Code or check Node.js/Ubuntu docs for your current best install path.

Set npm global packages to install without sudo:

mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Install Claude Code:

npm install -g @anthropic-ai/claude-code
claude

Claude plan recommendation

For serious website building, a paid Claude plan saves time. The $100/month Max 5x plan gives substantially more usage than Pro and includes access to Claude Code; the $200/month Max 20x tier is for daily heavy use. Pricing can change, so check Anthropic before buying.

When Claude Code asks which model to use, choose the highest Opus model available for planning, architecture, large refactors, and debugging. You can use faster/cheaper models for tiny edits, but Opus is usually worth it when the project is unfamiliar or the deployment is breaking.

Step 3: Install ICP CLI

ICP CLI is the command-line tool used here to build and deploy ICP projects. The official quickstart installs the ICP CLI package and the WebAssembly optimization tool through npm.

npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm

icp --version
ic-wasm --version

If you plan to build Motoko backends later, also install the Motoko package manager:

npm install -g ic-mops

For a simple static website, you may not need Motoko or Rust yet. Start with the asset canister path first, then add backend logic when the site actually needs it.

Optional local network dependency

On Windows, ICP's quickstart notes that local networks require WSL and Docker Desktop. If you only deploy to mainnet, you may not need the local network at first, but local testing is useful before publishing changes.

Quick sanity check:

mkdir -p ~/icp-sites
cd ~/icp-sites
icp --help

Step 4: Start a new website project

Create a dedicated folder for the website and run Claude Code from the project root. Do not run Claude Code from a huge parent folder full of unrelated projects.

mkdir -p ~/icp-sites
cd ~/icp-sites
mkdir my-icp-site
cd my-icp-site
claude

Starter prompt for Claude Code

Create a clean static website project that can be deployed to ICP with ICP CLI.

Requirements:
- Use a simple static or Vite-based frontend.
- Keep the project lightweight and easy to understand.
- Add a README with build and deploy commands.
- Add an icp.yaml configured for an asset canister named frontend.
- Add .ic-assets.json5 in the public folder.
- Do not deploy automatically.
- Before editing, inspect the folder and explain your plan.
- After editing, summarize every file changed and how to preview/build/deploy.

What Claude should create

File or folderPurpose
package.jsonScripts such as npm run dev and npm run build.
src/ or index.htmlYour website source files.
public/Static files copied into the build output.
public/.ic-assets.json5Asset canister rules, security headers, SPA fallback, hidden file handling.
icp.yamlICP CLI project configuration and asset canister recipe.
README.mdHow to edit, build, deploy, and maintain the site.

Step 5: Work with Claude Code correctly

Claude Code is powerful because it can inspect files, write code, run commands, and fix errors. Treat it like a fast junior developer with excellent memory: useful, but still requiring your review.

Good operating rules:

  • Ask Claude to inspect the project before editing.
  • Ask for a plan, approve the plan, then let it edit.
  • Use Git before major changes: git init, git add ., git commit.
  • Do not approve commands you do not understand. Ask Claude to explain them.
  • Keep deploy commands separate from code-generation commands so you control publishing.

Useful Claude prompts:

Inspect this project and tell me exactly how it builds and deploys with ICP CLI. Do not edit files yet.

Fix the build errors. Make the smallest safe changes and explain what changed.

Add a new page, but preserve the existing design system and do not break deployment.

Review this site for mobile layout, accessibility, broken links, and deployment issues.

Prepare this for ICP deployment, but do not run the mainnet deploy command until I approve.

For complex work, use the highest Opus model available. The extra reasoning is usually cheaper than wasting hours chasing broken configs.

Step 6: Add ICP asset canister configuration

For a website, the simplest ICP deployment target is an asset canister. It hosts static files like HTML, CSS, JavaScript, and images directly on ICP. ICP's asset canister docs explain that ICP CLI deploys a pre-built asset canister, creates it if needed, installs it, and syncs your build output directory.

Example icp.yaml:

canisters:
  - name: frontend
    recipe:
      type: "@dfinity/asset-canister@v2.2.1"
      configuration:
        dir: dist
        build:
          - npm install
          - npm run build

The important parts:

  • frontend is the canister name you deploy and update.
  • dir: dist must match the output folder created by your build command.
  • build tells ICP CLI what to run before upload.

Example public/.ic-assets.json5:

[
  {
    "match": ".well-known",
    "ignore": false
  },
  {
    "match": "**/*",
    "security_policy": "standard",
    "headers": {
      "Cache-Control": "public, max-age=0, must-revalidate"
    },
    "allow_raw_access": false
  },
  {
    "match": "assets/**/*",
    "headers": {
      "Cache-Control": "public, max-age=31536000, immutable"
    }
  },
  {
    "match": "**/*",
    "enable_aliasing": true
  }
]

Step 7: Build and test locally

Before deploying to mainnet, build the site and verify that the output folder exists. Most failed deployments are simple build/output-folder problems.

Build the website:

npm install
npm run build
ls -la dist

Start a local ICP network and deploy:

icp network start -d
icp network ping
icp deploy

Open the frontend URL shown in the deploy output. It will look like:

http://<canister-id>.localhost:8000/

Check project and canister state:

icp project show
icp canister list
icp canister status frontend

When finished:

icp network stop

If local testing fails, ask Claude Code to read the error and fix the smallest likely problem. Common issues are missing Node packages, a wrong build output folder, or a canister name mismatch.

Step 8: Deploy to ICP mainnet

Mainnet deployment puts your website on the public Internet Computer. Your frontend will be accessible at a canister URL first, then you can map a custom domain.

Build one last time:

npm run build

Deploy the frontend canister to mainnet:

icp deploy -e ic frontend

Your output should include a canister ID and a URL like:

https://<canister-id>.icp.net/

Verify the canister:

icp canister status frontend

If your deploy fails because the canister needs cycles or an identity setup, pause and follow the current ICP CLI guidance shown in your terminal. Run these help commands to see the exact current workflow:

icp identity --help
icp cycles --help
icp token --help

Security rule: keep your identity files and recovery material private. Never paste private keys, seed phrases, or account recovery text into Claude Code, chat tools, screenshots, or public support forums.

Step 9: Connect your own domain

By default, your site is live at the canister URL. To use your own domain, you need DNS records, a domain ownership file served by the canister, and a registration API call. Replace example.com with your domain.

Add the domain ownership file:

mkdir -p public/.well-known
echo 'example.com' > public/.well-known/ic-domains
npm run build
icp deploy -e ic frontend

Verify the file is live:

curl -sL https://<canister-id>.icp.net/.well-known/ic-domains

Add DNS records at your DNS provider:

TypeName / HostValue
CNAME or ALIASexample.comexample.com.icp1.io
TXT_canister-id<canister-id>
CNAME_acme-challenge_acme-challenge.example.com.icp2.io

Cloudflare note: use DNS only, not proxied, while registering. If Cloudflare Universal SSL interferes with certificate validation, disable it during registration and re-enable only after the domain is working.

Validate and register:

curl -sL -X GET "https://icp.net/custom-domains/v1/example.com/validate"

curl -sL -X POST "https://icp.net/custom-domains/v1/example.com"

curl -sL -X GET "https://icp.net/custom-domains/v1/example.com"

Wait for certificate provisioning. If the browser shows a certificate warning immediately after registration, give it several minutes, then test again in a private/incognito window.

Step 10: Update, sync, and maintain

Once the site is live, your normal workflow is simple: edit, build, test, deploy, verify. Keep changes small and recoverable.

Everyday update workflow:

git status
# edit with Claude Code
npm run build
icp deploy -e ic frontend
# or, when only static assets changed:
icp sync -e ic frontend

When to use deploy vs sync:

UseWhen
icp deploy -e ic frontendYou changed config, build process, or anything that may need a full reinstall/update.
icp sync -e ic frontendYou only changed built static assets and want to upload changed files faster.

Troubleshooting checklist:

  • Build output empty? Confirm dir in icp.yaml matches the real output folder.
  • 404 on refresh? Make sure .ic-assets.json5 has enable_aliasing: true.
  • Custom domain validation fails? Check DNS, the .well-known file, and hidden-directory handling.
  • Wrong site deploys? Check the canister name in icp.yaml and the deploy command.
  • Ask Claude to explain every error message before trying random fixes.

Reusable Claude Code prompt

Use this prompt when you want Claude Code to create or repair an ICP website project. Replace bracketed text with your own details.

I want to launch a website on ICP using ICP CLI.

Project goal:
[Describe your website: business site, community page, portfolio, app landing page, etc.]

Requirements:
- Build a clean, fast, mobile-friendly static website.
- Configure it for ICP CLI with an asset canister named frontend.
- Use icp.yaml for deployment configuration.
- Use public/.ic-assets.json5 for asset settings.
- Include support for a future custom domain by adding public/.well-known/ic-domains with
  placeholder domain example.com.
- Use npm scripts: dev, build, preview if applicable.
- Add a README explaining local preview, ICP local deploy, mainnet deploy, custom domain
  steps, and update workflow.
- Do not deploy automatically.
- Do not add unnecessary dependencies.
- Inspect the folder first, explain your plan, then make the smallest safe implementation.
- After editing, summarize all files changed and the exact commands I should run next.

For an existing project, add this line:

This project already has files. Preserve the existing design and do not rewrite the whole app unless necessary.

Best practices before sharing your site

A working deployment is not the same as a trustworthy website. Before you send traffic to it, make the site clear, complete, and safe.

  • Add a clear headline and a simple call to action.
  • Add About, Contact, Privacy Policy, and Terms pages if you will run ads or collect leads.
  • Use a custom domain if you want credibility beyond the canister URL.
  • Compress images before upload so your site stays fast.
  • Test on mobile, desktop, and private/incognito browser windows.
  • Keep a private backup of your project and identity material.

If you are running paid ads

Make the landing page focused and trustworthy. Avoid unsupported claims, sensitive personal targeting, misleading guarantees, and broken links. If you use remarketing or analytics, make sure your privacy policy explains how data and cookies may be used.

Simple launch checklist

  • Ubuntu/terminal works
  • Node.js current enough
  • Claude Code installed
  • ICP CLI installed
  • Project builds
  • Local deploy works
  • Mainnet deploy works
  • Canister URL works
  • Custom domain file deployed
  • DNS records added
  • Domain registered
  • HTTPS works
  • Pages and links tested

Sources and current notes

This guide was generalized from a real website launch workflow — the same one behind the site you are reading right now — and checked against official documentation. Commands and pricing can change, so verify the latest docs if something fails.

TopicWhere to verify
Microsoft WSL installationlearn.microsoft.com/windows/wsl/install
Claude Code npm installationcode.claude.com/docs/en/setup
Claude plan comparison and Max plan pricingsupport.claude.com
ICP CLI quickstart and installationdocs.internetcomputer.org/getting-started/quickstart and github.com/dfinity/icp-cli
ICP asset canister configurationdocs.internetcomputer.org/guides/frontends/asset-canister/
ICP custom domainsdocs.internetcomputer.org/guides/frontends/custom-domains/

In my own launch, the site was deployed to an ICP asset canister, then the custom domain was connected by adding DNS records, deploying the .well-known/ic-domains file, validating the domain, registering it, and waiting for HTTPS certificate provisioning. Use your own domain and canister ID — and enjoy having a website that runs entirely on the Internet Computer.

Want help applying this to your situation?

Schedule a One-on-One Call With Me

$96 for a private 30-minute one-on-one call with me. Pick any time that works for you.

Schedule a one-on-one call with me and bring the exact thing you are stuck on. We can look at your channel, website, AI workflow, ICP setup, book, business, dating pattern, communication, health habits, or next step — and you will leave the call with a clear plan for exactly what to do next.