twoslash for C# — extract rich symbol metadata from C# code using Roslyn, for rendering beautiful code snippets in docs, blogs, and slides.
TypeScript has twoslash, which extracts compiler-derived type information and renders it inline in code snippets. C# has nothing equivalent. Documentation authors either manually annotate code or ship plain syntax-highlighted blocks with no type information.
Run glosharp against C# code and get:
- Hover information — type signatures, XML doc comments, just like VS/VS Code tooltips
- Compile verification — fail in CI if the code doesn't compile
- Structured metadata — JSON output that integrations can consume
- Beautiful rendering — via Expressive Code plugin, Shiki transformer, or standalone HTML/CSS
- How does twoslash work internally? What's the data model? → 01-twoslash-architecture
- What Roslyn APIs do we need for symbol metadata extraction? → 02-roslyn-metadata-extraction
- How do Shiki transformers and Expressive Code plugins work? → 03-shiki-and-expressive-code
- How do we resolve NuGet packages for compilation? → 04-nuget-resolution
- How do people manage code snippets in docs today? → 05-code-snippet-management
- What doc/blog frameworks should we target? → 06-doc-framework-landscape
- Architecture — system components and data flow
- Data format — output metadata JSON schema
- Integration points — Shiki, Expressive Code, standalone renderer
- Decisions — key decisions log
glosharp compact-complog <input.complog> -o <out.glocontext> compacts a Basic.CompilerLog .complog into a small, git-friendly .glocontext file that captures just what Glo# needs to resolve types, hovers, and completions.
The compactor:
- rewrites each reference assembly with JetBrains.Refasmer so only public API metadata is retained (method bodies, private types, and internals are stripped);
- drops analyzer DLLs, original source text, and generated source text — they are not needed for symbol-only rendering;
- deduplicates identical post-refasm references across compilations and stores each one once by SHA-256;
- writes a
GLOCTX-magic header followed by a zstd-compressed tar containing a deterministicmanifest.jsonplusrefs/<hash>.dllblobs.
Typical results: a ~7 MB BCL-only complog shrinks to ~1.2 MB, and a ~16 MB ASP.NET complog to under 3 MB. Output is byte-deterministic, so a checked-in .glocontext only changes when the underlying compilation context actually changes. The --complog flag on process, verify, and render auto-detects either format by magic bytes.
The zstd codec is provided by
ZstdSharp.Porttoday. Once .NET 11 ships, the codec will be swapped forSystem.IO.Compression's built-in zstd with no format change.The file header reserves baseline id/version slots for a future v2 format that layers
zstd --patch-fromover a shipped baseline artifact. v1 readers must reject any file with non-zero baseline fields so that v2 output does not silently resolve to a broken v1 reader.