Skip to content
A view engine for ASP.Net MVC using the Pug template engine
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


This is a view engine for ASP.NET MVC using the Pug (formerly Jade) template engine for NodeJS.

As of now, it only supports MVC 5. MVC 6 (ASP.Net Core) support is planned, but Edge.js (which PugViewEngine uses to execute Pug) is still working on .Net Core support.

Installation/Building From Source

Can be installed from NuGet:

PM> Install-Package PugViewEngine

Building From Source


Additional configurations may work, but this is all I have tested so far. I hope to support MonoDevelop on OS X and Linux, and the dotnet cli once .Net Core support is added.


In your Global.asax.cs file, add the following line at the end of the Application_Start() method:

ViewEngines.Engines.Add(new PugViewEngine.PugViewEngine());

When processing views, MVC will use Pug for views with the .pug extension and Razor for .cshtml. If you want to remove Razor entirely:

ViewEngines.Engines.Clear(); // call this first to clear all view engines
ViewEngines.Engines.Add(new PugViewEngine.PugViewEngine()); // then this to add PugViewEngine


Just create views as you normally would, just using the .pug extension instead of .cshtml, and Pug syntax instead of Razor syntax.

Within the view, you will have 3 JavaScript objects available: model, viewBag, and html.


model is your the model passed to the view. If your C# code looked like this:

public class PersonModel
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }


// in PersonController
public ActionResult View()
    PersonModel model = new PersonModel{
        FirstName = "John",
        LastName = "Doe",
        Age = 35

    return View(model);

in your view you can do something like:

// in Views/Person/View.pug
h2 Person
  li First Name: #{model.FirstName}
  li Last Name: #{model.LastName}
  li Age: #{model.Age}

and the resulting HTML will be:

    <li>First Name: John</li>
    <li>Last Name: Doe</li>
    <li>Age: 35</li>


You can use viewBag the same way. You can set the value in C#:

ViewBag.Message = "This is our message.";

and in the Pug view:

h2 Message:
p= viewBag.Message

resulting in:

<p>This is our message.</p>


modelErrors is a collection of key-value pairs, where the key is the model property name and the value is the error message string. It is populated from the ModelState.

Example of a login form using modelErrors to display error messages (using Bootstrap for styling):

form(novalidate="novalidate", action="/login", method="post")
  each error in modelErrors.filter(e => e.Key === "")
      = error.Value
  .form-group(class=modelErrors.some(e => e.Key === "Email") ? "has-error" : "")
    label.control-label(for="Email") Email:
    each error in modelErrors.filter(e => e.Key === "Email") error.Value
  .form-group(class=modelErrors.some(e => e.Key === "Password") ? "has-error" : "")
    label.control-label(for="Password") Password:
    each error in modelErrors.filter(e => e.Key === "Password") error.Value
      input#RememberMe(type="checkbox", name="RememberMe", value="true", checked=model.RememberMe)
      | Remember Me?
  input.btn.btn-primary(type="submit", value="Log in")


html provide various helpers, similar to @Html in Razor views. In fact, most of the Pug html helper functions call Razor's @Html helper behind the scenes.

Here are all the helpers that are implemented so far:

  • action - Renders a child action
  • That's it right now, more to come soon. Pull requests welcome.

Html Helpers


action(actionName, controllerName, routeValues)

Renders a child action. Calls HtmlHelper.Action() behind the scenes. The view engine the child view uses doesn't matter, this helper will insert the rendered HTML.

actionName and controllerName are strings, while routeValues is a JavaScript object. controllerName can be null if the child action is in the same controller as the current action.

div.nav-bar= html.action("NavBar", "Common", null)
div.article= html.action("Article", null, {articleId: 4})

The first example would render the NavBar() action in the CommonController controller class. The second example would render the Article(int articleId) action in the same controller the current action is in, passing a value of 4 in the articleId parameter.

You can’t perform that action at this time.