Bob Plugin Mode¶
By default, kiln generate handles everything: it runs bob internally to read
your schema, then generates the API layer. This is the recommended approach for
most projects.
For teams already using bob's code generation pipeline, kiln is also available as a bob plugin. This lets you run bob and kiln in a single pass - one command, one process - instead of running them separately.
When to use the plugin¶
- You already have a custom
main.gothat runsbobgen-psql(orbobgen-mysql/bobgen-sqlite) - You want bob models and kiln's API layer generated together
- You want to add other bob plugins alongside kiln
If you're starting fresh, use kiln generate instead. It's simpler and does
the same thing.
Install¶
The plugin is part of the main kiln module:
Setup¶
Create a gen/main.go in your project. This replaces running bobgen-psql
directly - you need a custom entrypoint to load plugins.
package main
import (
"context"
"log"
"os"
"os/signal"
"github.com/stephenafamo/bob/gen"
"github.com/stephenafamo/bob/gen/bobgen-psql/driver"
"github.com/stephenafamo/bob/gen/plugins"
kilnplugin "github.com/fisayoafolayan/kiln/plugin"
)
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
// Bob config
driverConfig := driver.Config{DSN: os.Getenv("DATABASE_URL")}
config := gen.Config{} // or load from file
// Bob's default plugins (models, factory, etc.)
bobPlugins := plugins.Setup[any, any, driver.IndexExtra](
plugins.Config{}, gen.PSQLTemplates,
)
// Kiln plugin - generates API layer
kiln := kilnplugin.New[any, any, driver.IndexExtra](kilnplugin.Options{
ConfigPath: "kiln.yaml",
})
state := &gen.State[any]{Config: config}
allPlugins := append(bobPlugins, kiln)
if err := gen.Run(ctx, state, driver.New(driverConfig), allPlugins...); err != nil {
log.Fatal(err)
}
}
Then run:
This generates bob models and kiln's API layer in a single pass.
Plugin options¶
kilnplugin.Options{
// Path to kiln.yaml. Defaults to "kiln.yaml".
ConfigPath: "kiln.yaml",
// Override the Go module path. If empty, read from go.mod.
ModulePath: "",
// Overwrite user-modified files (same as --force flag).
Force: false,
// Where status messages are written. Defaults to os.Stdout.
Output: os.Stdout,
}
How it works¶
kiln implements bob's DBInfoPlugin interface:
Bob calls PlugDBInfo after database introspection, passing the full schema.
kiln converts it into its internal representation and runs the same generators
that kiln generate uses. The output is identical.
Other databases¶
Replace the driver import for MySQL or SQLite:
MySQL:
SQLite:
The rest of the setup is the same.
Plugin vs CLI¶
kiln generate |
Bob plugin | |
|---|---|---|
| Setup | kiln.yaml only |
Custom gen/main.go + kiln.yaml |
| Bob models | Generated internally | Generated by your pipeline |
| Other bob plugins | Not supported | Add as many as you want |
| Recommended for | Most projects | Teams with existing bob pipelines |
Both produce identical output. The plugin just changes how bob and kiln are orchestrated.
Example¶
See the Team Task Tracker for a complete working example using kiln as a bob plugin.