SourceBrowser pre-renders your source code into static HTML and keeps only search on the server
Source browser website generator that powers https://source.dot.net, https://referencesource.microsoft.com and https://sourceroslyn.io
At a glance
- What is it?
- SourceBrowser is a C# generator that analyzes C# and VB with Roslyn and writes a static HTML site where every link and colour is precomputed, with only the search service running on a web server. It fits a team that wants a browsable code reference for its own solution, and it does not fit a codebase that needs search to work without a hosted ASP.NET Core site.
- Who is it for?
- SourceBrowser fits a team that wants a permanent, linkable code reference for a solution it already controls, and it does not fit a team that needs an incrementally generated site, a subdirectory deployment, or a search experience that works without running a server.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 101 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The generator is not incremental, and that shapes everything
SourceBrowser is a source browser website generator that powers referencesource.microsoft.com, sourceroslyn.io and source.dot.net. The conceptual design section is the part to read carefully, because it explains a set of constraints that look like limitations until you see why they exist.
The generator is not incremental. You have to generate into an empty folder from scratch every time, and then replace the currently deployed folder with the new contents atomically, using for example Azure Deployments or robocopy /MIR to inetpub\wwwroot. For smaller projects, deploying to Azure using Dropbox or Git would work just fine.
That single design choice explains most of the architecture. Because a full regeneration is the model, the output can be entirely precomputed, and because the replacement is atomic, a user never sees a half-updated site. The cost is that every build pays the full indexing cost, and there is no incremental path to fall back on.
This is a reference implementation that showcases the concepts and Roslyn usage, and the project status section is unusually blunt about it. It comes with no guarantees, use it at your own risk. There are no further plans to do any work in this repo, and any significant rearchitecture, adding large features, big refactorings won't be accepted because of resource constraints. The advice given to users is to feel free to use it to generate websites for your own code, integrate in your CI servers and do whatever you want in their own forks, with bug reports still accepted but with no guarantees or expectations.
Roslyn analyses the code, and everything else is precomputed HTML
At indexing time, C# and VB source code is analyzed using Roslyn and a lot of static hyperlinked HTML files are generated into the output directory. There is no database. The website is mostly static HTML where all the links, source code coloring and similar are precalculated at indexing time, and all the hyperlinks are hardwired to be simple links bypassing the server.
The single component that runs on the webserver is a service that, given a search query, does the lookup and returns a list of matching types and members, which are hyperlinks into the static HTML. The service keeps a list of all declared types and members in memory, and that list is also precalculated at indexing time. All services such as Find All References and Project Explorer are pre-rendered.
The reasoning behind this is a good example of a design that trades a small server component for a large static surface. A source browser is read far more often than it is searched, and search needs an index while navigation does not. By pushing all the navigation into pre-rendered HTML, the served site is cheap to host, cacheable at every level, and linkable, because a URL to a type is a real file rather than a request that happens to produce one.
The consequence for a user is stated plainly: it does require an ASP.NET Core website for hosting, because the symbol index is kept server-side, so without ASP.NET Core the search function doesn't work. The project links to its own architecture notes on the server-side part.
The one dynamic thing on the page, the search, is also the one thing that needs a server. Everything else is a file.
Building needs Visual Studio 2019, and the scripts do the rest
The build instructions are short and specific about their requirements.
git clone https://github.com/KirillOsenkov/SourceBrowser
cd SourceBrowser
Build.cmdVisual Studio 2019 is required to build Source Browser, and the README says so in a separate note as well, which suggests it is a frequent stumbling block.
There are two more scripts for the test loop. GenerateTestSite.cmd generates a site, and RunTestSite.cmd runs it. To work inside Visual Studio 2019, you open SourceBrowser.sln, set the HtmlGenerator project as startup and hit F5, and it is preconfigured to generate a website for TestCode\TestSolution.sln.
From there, the generator takes a set of command-line arguments that describe what to index and where to put it. You pass a path to an .sln file or a .csproj file, or multiple paths separated by spaces, to create an index for them. /out:<path> configures where to generate the website to, and that path is then used as the physicalPath when you run the server. /in:<path> passes a file with a list of full paths to projects and solutions to include in the index. /root:<path> preserves relative .sln folders rather than merging all solutions, and that folder must contain all the specified .sln or .csproj paths.
Finally you set the SourceIndexServer project as startup and run or debug the website. The flow is generator, then server, and the two are separate projects in the solution, which matches the architecture where generation is a build-time step and the server holds only the search index.
The repository layout follows that split, with src/ and lib/ holding the implementation, TestCode/ holding the sample solution the test scripts use, and a key.snk file for strong naming the assemblies.
The feature list is what a code reference actually needs
The features list is the best available description of what a generated site gives you, and reading it tells you what kind of reference this produces.
The navigation is layered. A Solution Explorer shows the contents of projects merged into a single tree on the left. A Project Explorer appears in any document via the Project link at the bottom. A Namespace Explorer shows, for a project, all types and members nested in a namespace hierarchy. A Document Outline displays the types and members in the current file from a button in the top right. Go To Definition works by clicking on a reference, and Find All Reference by clicking on a definition.
The colouring covers C#, VB, MSBuild, XAML and TypeScript. TypeScript files are indexed if they are part of a C# project, and work is underway to allow an arbitrary array of TypeScript files.
There are a few details that show what a real reference site needs. An i.txt at the solution URL, or at /AssemblyName/i.txt for an assembly, displays source code stats and lines of code. Clicking on the partial keyword displays a list of all files where that type is declared. MSBuild files such as .csproj have hyperlinks. Search for GUIDs in C# and VB string literals is supported, which is a very specific capability that only someone who has actually searched a large codebase for a hardcoded GUID would think to add.
The one-off feature is called out as such. A URL fragment of #EmptyArrayAllocation finds all allocations of empty arrays, and the README notes this feature is one-off and hardcoded and not extensible. It is a nice illustration of the pattern: a static site can host a single hand-written analysis, but only as a fixed URL, because there is no server to run it on demand.
Two limitations that are consequences of the design, not oversights
The limitations section names two problems, and both trace back to a deliberate choice rather than to laziness.
The first is duplicate assembly names. Indexing more than one project with the same assembly name is currently unsupported, and only the first project wins. The README is explicit that this is due to a fundamental design decision to only reference an assembly by short name, and it suggests that customizers should add a means to filter victim projects out in their forks to pick the best single project for inclusion in the index.
That is a real constraint in practice. Assemblies are referenced by short name in source, so a type reference has to resolve to a single assembly, and if two projects in your solution produce the same assembly name, the generator cannot know which one you meant. The workaround the project suggests, filtering in a fork, is honest but it means every consumer with this problem has to patch it themselves.
The second limitation is deployment shape. The generated website can only be hosted in the root of the domain, and making it run from a subdirectory is non-trivial and unlikely to be supported. Again this follows from the design: the hyperlinks are hardwired as simple links bypassing the server, so a site under a path prefix would need every generated link to carry that prefix, and the generator is not built to do that.
Together these two limitations define the deployment envelope. A source browser at the root of a domain, with uniquely named assemblies, is what the tool supports. Anything else means forking.
The licence is Apache-2.0, which is permissive and carries no copyleft obligation for a generated internal site, and there is a SECURITY.md at the root alongside a CODE-OF-CONDUCT.md.
The soft archive and the fork are the deciding factors
The README opens with a warning and a tip, and both matter more than anything else in the document.
The warning says the project is soft-archived, and that at this point the author is unlikely to take even the basic PRs. The stated reason is personal and worth reading as a signal about the project's future: the author says he has given this project everything he could give over 13 years and is afraid he has nothing else left.
The tip says tannergooding is carrying the project forward at a fork, with lots of perf and other improvements there. The credit is explicit and the fork is named in the tip at the top of the README, which is unusual courtesy from a maintainer handing over a project.
That is the whole adoption decision for most people. If you want this capability, use the fork, because it is the one that will receive work. The original repository is a reference implementation, its own site is browsable at sourcebrowser.azurewebsites.net, the package is on NuGet as SourceBrowser, and the last tagged release is v1.0.21 from 2019-05-29. The last push to this repository was on 2026-07-14.
The instructions to use it are therefore best read as instructions for running a fork. The project explicitly invites that: feel free to use it to generate websites for your own code, integrate in your CI servers, and do whatever you want in your own forks. A team that wants a permanent code reference for its own solution can take the whole thing, run the generator in its build pipeline, and deploy the output folder atomically, which is the workflow the design is built around.
Editorial conclusion
SourceBrowser fits a team that wants a permanent, linkable code reference for a solution it already controls, and it does not fit a team that needs an incrementally generated site, a subdirectory deployment, or a search experience that works without running a server. Before adopting it, read the soft-archive notice at the top of the README, because the original author states he is unlikely to take even basic pull requests, and consider the fork at tannergooding/SourceBrowser, which the README credits with performance and other improvements.
Frequently asked questions
What is SourceBrowser?
It is a C# website generator for browsing C#, VB, MSBuild, XAML and TypeScript source code, and it powers referencesource.microsoft.com, sourceroslyn.io and source.dot.net. It indexes code with Roslyn and writes static hyperlinked HTML, with only the search service running on the web server.
Does SourceBrowser need a web server?
Yes, for search. The generated site is static HTML with precomputed links and colouring, but the symbol index is kept server-side, so an ASP.NET Core site is required and without one the search function does not work. The rest of the browsing works from the static files.
Is SourceBrowser still maintained?
The repository is soft-archived. The author states he is unlikely to take even basic pull requests after 13 years of work, and the README points to tannergooding/SourceBrowser as the continuation, with performance and other improvements. Bug reports are still accepted but with no guarantees, and the last push was on 2026-07-14.
What are the known limitations of SourceBrowser?
Indexing more than one project with the same assembly name is unsupported, because assemblies are referenced by short name and only the first project wins, so forks are expected to filter duplicates. The generated site can also only be hosted in the root of the domain, since running it from a subdirectory is non-trivial and unlikely to be supported.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kirillosenkov-sourcebrowser)Was this useful?