Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";
import mdx from "@astrojs/mdx";

export default defineConfig({
site: process.env.SITE_URL ?? "https://wezel.build",
base: process.env.SITE_BASE ?? "/",

// /docs has no landing page of its own — send it to the introduction.
redirects: {
"/docs": "/docs/introduction",
},

// Code blocks in the hand-authored landing body (src/home/index.mdx).
// Starlight manages its own theming for docs separately.
markdown: {
shikiConfig: { theme: "vitesse-dark", wrap: false },
},

integrations: [
starlight({
title: "Wezel Docs",
Expand Down Expand Up @@ -40,8 +52,15 @@ export default defineConfig({
autogenerate: { directory: "docs/developing" },
},
],
customCss: [],
customCss: ["./src/styles/starlight.css"],
head: [
// Light-only: pin the theme so expressive-code and everything else
// render light, regardless of OS preference or any stored value.
{
tag: 'script',
content:
"try{localStorage.setItem('starlight-theme','light')}catch(e){}document.documentElement.dataset.theme='light';",
},
{
tag: 'script',
attrs: {
Expand All @@ -52,5 +71,8 @@ export default defineConfig({
},
],
}),
// mdx() must come after starlight() — Starlight registers
// expressive-code, which has to be set up before MDX.
mdx(),
],
});
47 changes: 42 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
"preview": "astro preview"
},
"dependencies": {
"@astrojs/mdx": "^4.3.14",
"@astrojs/starlight": "^0.37.6",
"@fontsource/ibm-plex-sans": "^5.2.8",
"@fontsource/iosevka": "^5.2.5",
"@fontsource/iosevka-aile": "^5.2.5",
"astro": "^5.10.0"
"astro": "^5.10.0",
"ci-info": "^4.4.0"
}
}
4 changes: 4 additions & 0 deletions public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 2 additions & 15 deletions src/content.config.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
import { defineCollection, z } from "astro:content";
import { defineCollection } from "astro:content";
import { docsLoader } from "@astrojs/starlight/loaders";
import { docsSchema } from "@astrojs/starlight/schema";
import { glob } from "astro/loaders";

export const collections = {
docs: defineCollection({
loader: docsLoader(),
schema: docsSchema(),
}),
blog: defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
date: z.coerce.date(),
draft: z.boolean().default(false),
author: z
.union([z.string(), z.array(z.string()).min(1)])
.transform((v) => (Array.isArray(v) ? v : [v])),
}),
}),
};
};
5 changes: 0 additions & 5 deletions src/content/docs/docs/index.md

This file was deleted.

65 changes: 65 additions & 0 deletions src/home/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## Why?

I feel like build times are an afterthought. Yes, people spend countless hours complaining about them. Yes, the pain is real. Yet the trend is for them to get worse, not better. There's never enough time in a day to get them into shape.

We do not talk about our issues enough, because nobody wishes to *care* about their build. It's a boring topic. Rightly so. You want to spend your sweet time on tackling problems you're paid to solve.

### Sufficiently swift compiler
It's not like we can expect a sufficiently swift compiler to show up and wave all of your issues away either. We cannot expect toolchain maintainers to:
1. know what is painful about your usage of the toolchain.
2. have access to your codebase in order to poke, prod and profile a compiler.

Even if such compiler existed, chances are that [Jevons paradox](https://en.wikipedia.org/wiki/Jevons_paradox) would do you dirty.

### Optimizing builds requires obscure knowledge

Material on optimizing builds is few and far between, stowed away on internet forums or blog post entries. In a way, you have to have quite intricate understanding of the compiler internals in order to really squeeze your build.
Knowing how big of an impact that using a given dependency will have on your builds is nigh impossible. So is structuring code around monomorphizations or dynamic dispatch. Yet, down the line, these decisions can have collateral effect on your build performance.

### Speed is a cultural challenge
It's quite tricky to keep code written a particular way. In my experience, code that's quicker to compile is "uglier", as you have to limit how much a compiler has to do. Sure, you can stick a comment on it, but there's no way to be *certain* that code you've made quick to compile will stay that way - especially in the era where the human might not necessarily be in the loop.

### Putting it all together
We're left in a situation where optimizing builds is a skill on its own, whose fruits are hard to hold onto. Nobody will do that for you and while you may be tempted to just skip this relatively boring chore, you'll feel the pain of that negligence yourself. That's why I've built Wezel - I want people to know when (and eventually - why) their build regressed

## What

Wezel lets you define build scenarios you want to track across the lifetime of your project.
It all starts with an `experiment.toml`, committed next to your code, that declares what to measure.
Take the following example The `cargo` tool builds your target and emits timing outcomes, and a
single outcome can feed several summaries.

```toml
description = "Tracks compile time of the wezel workspace"

# A single experiment consists of multiple steps, executed in order
[step.cargo.release-build]
command = "build"
build_target = ["burrow"]
profile = "release"
# Summaries are outputs of a step of an experiment.
# They're always scalar (to drive the bisection).
# Summaries use outcomes to get their values.
# Outcomes are results of your experiments - they are not necessarily scalar!
# (think of e.g. compiler profiling files or cargo --timings output)
#
# In this case, `cargo` tool emits `time_ms` for a total time for a build.
# In order to produce a summary,
# we'll run 5 builds and take their mean build time as a value of `build-time` summary.
summary.build-time = { outcome = "time_ms", aggregation = "mean", samples = 5 }
```

Most commits do not meaningfully regress your builds though. That's why we resort to sparse sampling: instead of running these experiments on every single commit you make, we run these measurements once a day or so.
Only when there's a meaningful regression between the last measurement and a current one do we resort to running experiments on all unmeasured commits - until all sources of regressions are found.

The results of experiment runs are surfaced in a dashboard over at [app.wezel.build](app.wezel.build).

### Not just Rust

The whole thing is extensible - tool implementations live in separate binaries. Nothing prevents you from adding support for your own toolchain of choice - as long as you follow the protocol.

## Where

Wezel is open source and under active development. Follow along on
[GitHub](https://github.com/wezel-build/wezel), read the
[quickstart](/docs/quickstart) to wire it into your own builds. There's also [Discord server](https://discord.gg/NE6HAz7H) you can join to chat and follow along.
50 changes: 2 additions & 48 deletions src/layouts/Base.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,24 @@ interface Props {
const { title = "Wezel — Your build, always at its best." } = Astro.props;

const navLinks = [
{ label: "Blog", href: "/blog" },
{ label: "Docs", href: "/docs" },
{ label: "Status", href: "https://status.wezel.build" },
];

const themes = ["dark", "light"] as const;
---

<!doctype html>
<html lang="en">
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Wezel is an open-source build observability suite that catches regressions before they slow your team down." />
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%23b08868'/%3E%3Ctext x='50%25' y='54%25' dominant-baseline='middle' text-anchor='middle' font-family='monospace' font-weight='bold' font-size='18' fill='%23141210'%3Ew%3C/text%3E%3C/svg%3E" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="preload" href={iosevkaAile600Url} as="font" type="font/woff2" crossorigin />
<title>{title}</title>
<script defer src="https://cloud.umami.is/script.js" data-website-id="83b509e2-8cc4-430d-a0aa-876262ff4082"></script>
</head>
<body>
<script is:inline>
(function() {
var t = localStorage.getItem('theme') || 'dark';
if (t === 'slate') { t = 'dark'; localStorage.setItem('theme', t); }
document.documentElement.setAttribute('data-theme', t);
})();
</script>
<nav class="nav">
<div class="nav-inner">
<a href="/" class="nav-logo">
Expand All @@ -47,30 +38,12 @@ const themes = ["dark", "light"] as const;
{navLinks.map(link => (
<a href={link.href} class="nav-link">{link.label}</a>
))}
<button id="theme-toggle" class="theme-btn" type="button" aria-label="Switch theme">
dark
</button>
<a href="https://github.com/wezel-build/wezel" target="_blank" rel="noopener" class="btn btn-sm btn-secondary">
GitHub
</a>
</div>
</div>
</nav>
<script is:inline>
(function() {
var order = ['dark', 'light'];
var btn = document.getElementById('theme-toggle');
var current = localStorage.getItem('theme') || 'dark';
btn.textContent = current;
btn.addEventListener('click', function() {
var i = order.indexOf(current);
current = order[(i + 1) % order.length];
document.documentElement.setAttribute('data-theme', current);
localStorage.setItem('theme', current);
btn.textContent = current;
});
})();
</script>

<main>
<slot />
Expand Down Expand Up @@ -165,25 +138,6 @@ const themes = ["dark", "light"] as const;
color: var(--text);
}

.theme-btn {
background: var(--surface2);
border: 1px solid var(--border);
border-radius: 4px;
padding: 2px 10px;
cursor: pointer;
color: var(--text-mid);
font-size: 0.72rem;
font-family: var(--font-mono);
font-weight: 500;
letter-spacing: 0.02em;
transition: border-color 0.15s, color 0.15s;
}

.theme-btn:hover {
border-color: var(--text-dim);
color: var(--text);
}

/* ── Footer ──────────────────────────────── */
.footer {
border-top: 1px solid var(--border);
Expand Down
31 changes: 0 additions & 31 deletions src/lib/authors.ts

This file was deleted.

Loading
Loading