Your first app
About ten minutes. You end with a Svelte counter served by ASP.NET Core and reloading on save.
1. Make a web project
dotnet new web -o hello-husk
cd hello-husk
2. Add the packages
dotnet add package Extrode.Pare.Build --version 0.6.1
dotnet add package Extrode.Husk.Build --version 0.1.0-preview.1
dotnet add package Extrode.Husk.AspNetCore --version 0.1.0-preview.1
Open hello-husk.csproj and add PrivateAssets="all" to the two .Build references. They are build tools, not code your app needs at run time:
<PackageReference Include="Extrode.Pare.Build" Version="0.6.1" PrivateAssets="all" />
<PackageReference Include="Extrode.Husk.Build" Version="0.1.0-preview.1" PrivateAssets="all" />
<PackageReference Include="Extrode.Husk.AspNetCore" Version="0.1.0-preview.1" />
The first restore downloads the 82.6 MB Husk package. After that it is cached.
3. Write a component
Create wwwroot/App.svelte:
<script lang="ts">
let count = $state(0);
</script>
<button onclick={() => (count += 1)}>clicked {count} times</button>
<style>
button { font-size: 1.25rem; }
</style>
4. Write the entry point
Create wwwroot/main.ts:
import { mount } from 'svelte';
import App from './App.svelte';
mount(App, { target: document.getElementById('app') as HTMLElement });
5. Write the page
Create wwwroot/index.html:
<!doctype html>
<meta charset="utf-8">
<title>Hello Husk</title>
<link rel="stylesheet" href="/_husk/husk.css">
<script type="importmap" data-husk></script>
<div id="app"></div>
<script type="module" src="/main.js"></script>
The empty <script type="importmap" data-husk> is a marker. The build fills it with the paths of svelte and your files.
6. Serve it
Replace Program.cs:
using Extrode.Husk.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
builder.AddHusk();
var app = builder.Build();
app.Use((context, next) =>
{
if (context.Request.Path == "/")
context.Request.Path = "/index.html";
return next(context);
});
app.UseRouting();
app.MapStaticAssets();
app.Run();
MapStaticAssets serves no default document, so the small middleware sends / to /index.html.
7. Run it
dotnet watch
Open the address it prints. Click the button.
Now edit the text in App.svelte and save. The page reloads with the change. Break the markup on purpose and save: the error is logged and the browser keeps showing the last good version.
8. Build and publish
dotnet build
dotnet publish -c Release
Look under obj/: the compiled App.svelte.js, its source map and husk.css are there. dotnet publish ships them with compressed copies, and no .svelte or .ts sources.
If something goes wrong
| You see | It means |
|---|---|
HUSK002 |
Add the Extrode.Pare.Build reference. |
HUSK001 |
The build machine is Alpine, FreeBSD or another unsupported platform. |
HUSK100 |
Svelte rejected your component. The message names the line and column. |
| A blank page | Check the browser console. The usual cause is a missing data-husk marker or /main.js path. |
Every code: Error codes. Next: What the build produces.