Skip to content

bino Plugin SDK

Go SDK for building bino plugins.

Early access — The plugin API is subject to change.

What is bino?

bino is a CLI tool for building pixel-perfect PDF reports from YAML manifests and SQL queries. It uses DuckDB for analytical SQL and Chrome headless for PDF rendering. See the documentation for more.

What plugins can do

A single plugin binary can provide any combination of:

  • Custom DataSources — fetch data from SaaS APIs, proprietary databases, or any external system
  • Visual Components — ship Web Component JS/CSS for custom chart types or widgets
  • Lint Rules — validate manifests with domain-specific rules (with optional access to datasets and DuckDB)
  • Pipeline Hooks — react to build events (post-load, post-dataset, post-render-html, post-render-pdf)
  • CLI Commands — add subcommands to bino plugin exec <name>:<command>
  • Host Queries — call back to the bino host to execute DuckDB SQL, fetch documents, or retrieve dataset results

Quick start

go get github.com/bino-bi/bino-plugin-sdk@latest

Create main.go:

package main

import (
    "context"
    "encoding/json"
    "fmt"

    sdk "github.com/bino-bi/bino-plugin-sdk"
)

func main() {
    sdk.Serve(&sdk.PluginOpts{
        Name:        "myplugin",
        Version:     "0.1.0",
        Description: "My custom bino plugin",

        // Register a custom DataSource kind.
        Kinds: []sdk.Kind{{
            Name:           "MyDataSource",
            Category:       sdk.KindDataSource,
            DataSourceType: "my_api",
        }},

        // Handle data collection.
        CollectDataSource: func(ctx context.Context, req *sdk.CollectRequest) (*sdk.CollectResponse, error) {
            rows, _ := json.Marshal([]map[string]any{{"id": 1, "value": 42}})
            return &sdk.CollectResponse{JSONRows: rows}, nil
        },

        // Add a lint rule.
        LintRules: []sdk.LintRule{{
            ID:          "require-description",
            Description: "Every document should have a description",
            Check: func(ctx context.Context, docs []sdk.Document) []sdk.Finding {
                // ... inspect docs, return findings
                return nil
            },
        }},
    })
}

Build and install:

go build -o bino-plugin-myplugin .

# Place in project
cp bino-plugin-myplugin <your-project>/.bino/plugins/

Add to bino.toml:

[plugins.myplugin]

Verify: bino plugin list

API overview

sdk.Serve(opts)

Entry point — starts the gRPC server and blocks until the host terminates the plugin. Call this as the last line of main().

PluginOpts

Field Type Description
Name string Plugin name (must match bino.toml key)
Version string Semver version
Description string One-line description
Kinds []Kind Custom kind registrations
DuckDBExtensions []string DuckDB extensions to load
CollectDataSource func(ctx, *CollectRequest) (*CollectResponse, error) DataSource handler
LintRules []LintRule Lint rule definitions
Assets []Asset Static JS/CSS assets
GetAssets func(ctx, renderMode) ([]Asset, error) Dynamic asset callback
Commands []Command CLI subcommands
Hooks map[string]HookFunc Pipeline hook callbacks
RenderComponent func(ctx, *RenderRequest) (*RenderResponse, error) Component HTML renderer

Host access

Plugin callbacks receive a HostClient for querying the bino host:

CollectDataSource: func(ctx context.Context, req *sdk.CollectRequest) (*sdk.CollectResponse, error) {
    if req.Host != nil {
        // Query the host's DuckDB
        result, _ := req.Host.QueryDuckDB(ctx, "SELECT count(*) as n FROM other_source")
        // List loaded documents
        docs, _ := req.Host.ListDocuments(ctx, "DataSource")
    }
    // ...
},

Available on: CollectRequest.Host, RenderRequest.Host, HookPayload.Host, LintContext.Host, and via Command.RunWithHost.

Enriched linting

Use CheckWithContext for lint rules that need datasets or host access:

LintRules: []sdk.LintRule{{
    ID: "max-rows",
    CheckWithContext: func(ctx context.Context, docs []sdk.Document, lc *sdk.LintContext) []sdk.Finding {
        if lc.Host != nil {
            result, _ := lc.Host.QueryDuckDB(ctx, "SELECT count(*) as n FROM my_table")
            // ... check row count
        }
        return nil
    },
}},

Sample plugin (soon)

See sample-plugin/ for a complete working example demonstrating all capabilities:

  • Custom DataSource and Component kinds with JSON Schema
  • Data collection with JSON rows
  • Component HTML rendering (Web Component)
  • JS/CSS asset injection
  • Three lint rules (basic + enriched with CheckWithContext)
  • CLI commands with Run and RunWithHost
  • Pipeline hooks (post-load, post-dataset-execute, post-render-html)
  • Host access (QueryDuckDB, ListDocuments)

Platform notes

Plugins are native executables — you need a separate binary per platform:

Platform Binary name Notes
macOS bino-plugin-<name> May need codesign --force --sign -
Linux bino-plugin-<name> Must be executable (chmod +x)
Windows bino-plugin-<name>.exe .exe extension required

bino auto-appends .exe on Windows during discovery. Cross-compile with:

GOOS=linux   GOARCH=amd64 go build -o bino-plugin-myplugin .
GOOS=windows GOARCH=amd64 go build -o bino-plugin-myplugin.exe .
GOOS=darwin  GOARCH=arm64 go build -o bino-plugin-myplugin .

Project structure

bino-plugin-sdk/
  proto/v1/plugin.proto    # gRPC service contract (BinoPlugin + BinoHost)
  proto/v1/plugin.pb.go    # Generated message types
  proto/v1/plugin_grpc.pb.go # Generated gRPC stubs
  sdk.go                   # Serve() entry point, PluginOpts
  types.go                 # Public types (Kind, Document, Finding, Asset, ...)
  grpcserver.go            # gRPC server implementation
  hostclient.go            # HostClient for calling back to the bino host
  convert.go               # Proto ↔ Go type conversions

Documentation

Contributing

Contributions are welcome — see CONTRIBUTING.md for guidelines, development setup, and the proto backward-compatibility policy. Please also review our Code of Conduct and Security Policy.

License

Apache License 2.0

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages