dry-view is a simple, standalone view rendering system built around functional view controllers and templates. dry-view allows you to model your views as transformations, accepting user input and returning your rendered view.

Use dry-view if:

  • You want to build and render views consistently in any kind of context (dry-view is standalone, it doesn’t require an HTTP request!).
  • You’re using a lightweight routing DSL like Roda or Sinatra and you want to keep your routes clean and easy to understand (dry-view handles the integration with your application’s objects, all you need to provide from your routes is the user input data).
  • Your application uses dependency injection to make objects available to each other (dry-view fits perfectly with dry-web and dry-system).
  • You want a way to test your views in isolation.


Build your view controller:

require "dry-view"

class HelloView < Dry::View::Controller
  configure do |config|
    config.paths = [File.join(__dir__, "templates")]
    config.layout = "app"
    config.template = "hello"

  expose :greeting

Write a layout (templates/layouts/app.html.erb):

    <%= yield %>

And a template (templates/hello.html.erb):

<p><%= greeting %></p>

Then #call your view controller to render your view:

view =
view.(greeting: "Greetings from dry-rb")
# => "<html><body><h1>Hello!</h1><p>Greetings from dry-rb!</p></body></html>

Dry::View::Controller#call expects keyword arguments for input data. These arguments are handled by your exposures, which prepare view parts that are passed to your template for rendering.