Vapor Generators

VaporGenerators is a package that extends Vapor to add a command line tool that generates classes and files automagically for you. It is very much inspired from Rails' command line tools.


This Generators have been tested on macOS. Linux users beware: this might not work for you!


You can install the generators using 3 simple steps:

  1. Add this Package as a dependency to your project
  2. Configure your Droplet with the Generate command.
  3. Build your project

Step 1. Add this Package to your project

// In your project's Package.swift file
    dependencies: [
        .Package(url: "", majorVersion: 0),

Step 2. Configure your Droplet

// In your project's main.swift file
let drop = Droplet()
drop.commands.append(Generate(console: drop.console))

Step 3. Build your project

# In a Terminal window
cd /path/to/your/project
swift build


After you've installed the Generate command, you can use the generator from the command line, like so:

# In a Terminal window
cd /path/to/your/project
vapor run generate [generator-type] [arguments]
vapor build  # or
vapor xcode  # if you use Xcode or AppCode

See the list of generator types below for details of what generators are available and what arguments they accept.

Available Generators


Generates a model class and an associated test class.

For example, running the command vapor run generate model foo would produce the classes highlighted by this structure:

├── ...
├── Sources
|   └── App
|       ├── ...
|       └── Models
|           ├── ...
|           └── Foo.swift
└── Tests
    └── AppTests
        └── Models
            ├── ...
            └── FooTests.swift


name (required)

The name of the model. The generator always capitalizes this parameter before using it.

properties (optional)

A space separated list of strings in the format propertyName:propertyType.

E.g. vapor run generate model user firstName:string lastName:string would generate the following:

import Vapor
import Fluent
import Foundation

final class User: Model {
    fileprivate static let tableName = "users"
    var id: Node?
    var firstName: String
    var lastName: String
    init(node: Node, in context: Context) throws {
        id = try node.extract("id")
        firstName = try node.extract("first_name")
        lastName = try node.extract("last_name")
    func makeNode(context: Context) throws -> Node {
        return try Node(node: [
            "id": id,
            "first_name": firstName,
            "last_name": lastName,

extension User: Preparation {
    static func prepare(_ database: Database) throws {
        try database.create(User.tableName) {
    static func revert(_ database: Database) throws {
        try database.delete(User.tableName)


Generate Leaf views.


names (required)

A list of names for the views to generate.

--useFirstArgumentAsDirectory (optional)

If this flag is passed, the first name in the list is used as a directory name in which all other views are generated.


Generate a controller class. By default the command creates an empty controller. If you pass the --resource flag, it creates a controller that conforms to the Vapor.ResourceRepresentable protocol instead.


name (required)

The name of the controller. This can be either a singular resource name such as Post or a fully formed controller name such as PostsController. In both cases, the name PostsController is the final name the generator would use.

Example outputs

  • "Post" => "PostsController"
  • "PostsController" => "SettingsController"
  • "Keyboard" => "KeyboardsController"
  • "KeyboardController" => "KeyboardController"
actions (optional)

A space separated list of strings. By default this represent methods that the generated controller will implement. When the --resource flag is passed to the generator, the actions are interpreted as names of the Vapor.Resource actions to be implemented.


The command vapor run generate controller MyController foo bar would produce

import Vapor
import HTTP

final class MyController {
    let droplet: Droplet
    init(droplet: Droplet) {
      self.droplet = droplet
    func foo(request: request) throws -> ResourceRepresentable {
        return try droplet.view.make("my/foo")
    func bar(request: request) throws -> ResourceRepresentable {
        return try droplet.view.make("my/bar")


Generates a route with the specified parameters.


path (required)

The path to created relative to the root.

method (optional)

The HTTP method to use when creating the path. Defaults to get.

handler (optional)

A string representing code to execute as part of the route's handling closure. E.g. try droplet.view.make("index").

NOTE: Although available, you shouldn't really use this method. Simply generate the route and then use your favorite text editor or IDE to change the route's handling implementation.

--resource (optional)

When specified, the generator creates resource paths using Vapor's resource method and ignores the method and handler parameters.


vapor run generate route foo
// In your routes file
droplet.get("foo") { request in
    return JSON([:])
vapor run generate route bar --resource
// In your routes file
droplet.resource("bars", BarsController())

extension Droplet {
    func pathForBars() -> String {
        return "bars"
    func path(for model: _RESOURCE_) throws -> String {
        guard let id = else { throw Abort.badRequest }
        return pathForBars() + "/\(id)"
    func pathForCreatingBars() throws -> String {
        return try pathForBars() + "/new"
    func path(forEditing model: _RESOURCE_) throws -> String {
        return try path(for: model) + "/edit"


This produces a Model, Views, a Controller and Routes using the respective generators and passing the arguments along. Additionally, it creates style and script files for the specified resource.

For example, running vapor run generate resource user index show firstName:string lastName:string would create the following files:

├── ...
├── Public
|   ├── scripts
|   |   ├── ...
|   |   └── users.js
|   └── styles
|       ├── ...
|       └── users.css
├── Resources
|   └── Views
|       ├── ...
|       └── users
|           ├── index.leaf
|           └── show.leaf
├── Sources
|   └── App
|       ├── ...
|       ├── Models
|       |   ├── ...
|       |   └── User.swift
|       └── Controllers
|           ├── ...
|           └── UsersController.swift
└── Tests
    └── AppTests
        ├── ...
        ├── Models
        |   ├── ...
        |   └── UserTests.swift
        └── Controllers
            ├── ...
            └── MyControllerTests.swift

See the other generator's details to see how each file's content is generated.


See the parameters accepted by the other generators.


Generates a test class for the passed in class name. It also creates a LinuxMain.swift file if one is not found and updates it for each generated test case.


className (required)

The name of the class for which you want to generate tests or a the name of the test class itself. Valid inputs are:

  • MyController => will produce MyControllerTests
  • MyControllerTests => will produce MyControllerTests
  • TestMyController => will produce TestMyController
directory (optional)

The path where the test class is to be generated. Defaults to Tests/AppTests/. An example input would be Tests/AppTests/Controllers/.


You can customize the generate command to use your own generators like so:

// In your project's main.swift file
let generateCommand = Generate(console: droplet.console)
generateCommand["model"] = MyModelGenerator.self
generateCommand["my-custom-generator"] = MyCustomGenerator.self

To use your custom generators, you would run the same command as before:

# In a Terminal window
cd /path/to/your/project
vapor run generate model [arguments]
vapor run generate my-custom-generator [arguments]


  • Test on Linux
  • Add Unit Tests
  • Improve Pluralization code (and extract it in a new Package)


  • Swift Tools 3.1.0
View More Packages from this Author


Last updated: Tue Nov 08 2022 21:48:58 GMT-0500 (GMT-05:00)