WebKit is a hybrid Markdown + HTML site engine written in C#.
It transforms simple .md pages into clean, responsive websites — with built-in layouts, dark/light mode, and expression support.
- Responsive layout 📱
- Dark 🌙 + Light ☀️ mode
- Hybrid Markdown + HTML syntax
- Simple expressions with Getters + Setters
- Configurable via
webkit.json
dotnet tool install -g Boson.WebKitwebkit init -n MySite cd MySite webkit build webkit serveOpen http://localhost:3000 🎉
webkit.json
{ "Properties": { "Name": "MySite", "Author": "CodingBoson" } }Access with expressions:
# Welcome to {{ .Name }} by {{ .Author }}MySite/ ├─ build/ # Generated output ├─ Resources/ # All resources live here │ ├─ Pages/ # Markdown + hybrid HTML pages │ ├─ Shared/ # Reusable components │ ├─ Static/ # CSS, JS, images │ └─ Layout.html # Global layout ├─ .gitignore ├─ README.md └─ webkit.json # Site config webkit init <Name> # Create new site webkit build # Build static site webkit serve # Run local dev server webkit clean # Clear build outputThe Layout.html in Resources/ defines the global wrapper for your pages.
Every page gets rendered inside this layout.
Example:
<!DOCTYPE html> <html> <head> <title>{{ .Title }}</title> <link rel="stylesheet" href="/webkit.css"> </head> <body> {{ .NavBar }} <main> {{ .Content }} </main> <footer> <p>© {{ .Name }} by {{ .Author }}</p> </footer> </body> </html>In WebKit, shared components are just resources inside Resources/Shared/.
To use them:
- Create a file in
Resources/Shared/(e.g.NavBar.html) - Reference it in
webkit.json - Use it as a property in any page or layout
Resources/Shared/NavBar.html
<nav> <a href="/">Home</a> <a href="/About.html">About</a> </nav>webkit.json
{ "Properties": { "Name": "MySite", "Author": "CodingBoson", // First, define a property in the `webkit.json` that references the shared HTML/markdown file. "NavBar": "@Shared/NavBar.html" "NavBar": "@Shared/NavBar.html" } }Layout.html
<body> {{ .NavBar }} <main>{{ .Content }}</main> </body>- No new syntax → Components are just properties.
- No hidden magic → WebKit doesn’t treat
Shared/specially. It’s just a folder convention. - Uniform API → Whether you use
.Name,.Author, or.NavBar, it’s the same expression system.
This makes WebKit:
- Predictable → All resources behave the same
- Simple → No separate “component language”
- Composable → You can nest and reuse shared parts freely
# Expressions WebKit supports **expressions** inside Markdown and HTML. They are written with double curly braces: ```markdown {{ .Property }}A Getter inserts the value of a property.
Example:
Welcome to {{ .Name }} by {{ .Author }}With this config:
{ "Properties": { "Name": "MySite", "Author": "CodingBoson" } }Result:
Welcome to MySite by CodingBosonProperties in webkit.json can point to other resources, like files in Resources/Shared/.
{ "Properties": { "NavBar": "@Shared/NavBar.html" } }Now you can use:
{{ .NavBar }}WebKit will inline the content of Resources/Shared/NavBar.html.
A SetterExpression allows you to define or override a property inside a page.
Syntax:
{{ .Property = value }}Example:
{{ .Title = .Name Home }} # Welcome to {{ .Name }}Here:
.Titleis set to"MySite Home"- It can be used later in
Layout.html(e.g., inside<title>)
Setters can concatenate multiple values:
{{ .Title = .Name " - " .Author }}With:
{ "Properties": { "Name": "MySite", "Author": "CodingBoson" } }Result:
<title>MySite - CodingBoson</title>When WebKit resolves an expression:
- Check runtime Setters (defined in the current page)
- Check
webkit.jsonProperties - If value is a resource reference (e.g.,
@Shared/...), load its content - Fallback → leave the expression untouched
This makes expressions predictable:
- Pages can override defaults (via Setters)
- Layouts and Shared resources stay flexible
To write an expression literally (without evaluating it), escape with \\:
\\{{ .Author }}Result:
{{ .Author }}Expressions are the glue of WebKit:
- Getters → read values
- Setters → define or override values
- References → pull in resources
- All unified under one minimal syntax
👉 No custom DSL. 👉 No templates-within-templates. 👉 Just properties + resources, flowing through the build pipeline.
GPL-3.0 © BosonWare Technologies