Skip to content

A tiny and extendable C# library for generating static sites, inspired by Metalsmith


Notifications You must be signed in to change notification settings


Repository files navigation

AppVeyor Build AppVeyor tests Discord

A tiny and extendable C# library for generating static sites, inspired by Metalsmith. Metalsharp is guided by three basic principles:

  1. Small footprint: Use the smallest amount of code necessary,
  2. Extendable: Make it as easy as possible for anyone to develop and release plugins, and
  3. Approachable: Maintain thorough documentation to keep the code easy to read and the library easy to learn

Generating a website from a directory is as simple as the following (from ExampleWebsite):

new MetalsharpDirectory("Site")
    .Use(new Drafts())

Getting Started

To get Metalsharp, you can either build it from source, or get it on NuGet.

PM> Install-Package Metalsharp -Version 0.9.0-rc.1

Note that you will need NuGet 4.3.0 or higher to install Metalsharp with NuGet.

Configuring a Metalsharp Project Directory

It is recommended that a Metalsharp project use something like the following directory structure.

├── Site
│   ├──
│   └──
├── Static
│   └── style.css

Here we have a project in a ProjectFolder directory. At that level, you can place files irrelevant to the resultant website. Site content can go in a Site folder, and content that will be copied right through to the output can go in a Static folder. None of these are requirements, and as your mileage varies you can implement whichever structure you need.

Using Metalsharp

Let's walk though the example at the top. The quickstart can give you a more thorough glimpse at Metalsharp, and there's also a tutorial to create a practical website.

  1. Instantiate a new MetalsharpProject with the directory containing the files you want to manipulate:
new MetalsharpProject("Site")
  1. You can add a plugin by referencing its type if it has an empty constructor, like the Frontmatter plugin. This one will add a file's frontmatter to its metadata:
  1. If a plugin does not have an empty constructor, or if you prefer this syntax, you'll either need to use a provided extension method, or instantiate the plugin yourself. The Drafts plugin (one of the example plugins) removes files marked as drafts.
.Use(new Drafts())
  1. And if an extension to Metalsharp exists for a plugin, as does for all the plugins that come with Metalsharp, you can use that extension method. Markdown converts Markdown files in the input to HTML files in the output.
  1. Finally, we've got a Static folder with files we want to copy right through to the output, so let's include those in the output:
  1. When you've configured your plugin pipeline, call Build to execute the stack:

Creating a Custom Plugin

Creating a Metalsharp plugin is very easy. This tutorial demonstrates how to develop and publish a plugin. Fundamentally, all you need to do is implement IMetalsharpPlugin. Below is the code for the Markdown plugin:

public class Markdown : IMetalsharpPlugin
    public void Execute(MetalsharpDirectory project)
        foreach (var file in project.InputFiles)
            var name = Path.GetFileNameWithoutExtension(file.Path);
            var text = Markdig.Markdown.ToHtml(file.FileText);
            project.OutputFiles.Add(new OutputFile(name + ".html", text) { Metadata = file.Metadata });


Metalsharp.Documentation houses generated API docs and hand-written tutorials.

The source code is fullly documented with XML comments, and XmlDocToMarkdown is used to generate a markdown dump of all the API documentation.

If you notice any issues or potential improvements in the documentation or tutorials, please edit the file(s) and submit a PR, it would be a huge help! If you don't have the time or skill to do that, then opening an issue would be awesome too.

If you have a question or need help using Metalsharp, please do not open an issue. Rather, head on over to the Metalsharp Discord for general questions and help.


If you'd like to contribute, please do! Open an Issue, submit a PR, I'm happy however you want to contribute.


v0.9.0-rc.1 is on NuGet! The current goal is to test the library thoroughly in as many situations as possible to be sure of its design and usability. This will involve generating a GitHub Pages homepage for Metalsharp, and it may involve writing integration tests. v0.9.0 will be released to Nuget when there is a concensus that Metalsharp is designed correctly.

After v0.9.0, it's on to v1.0.0!

But why is this necessary?