This guide shows you how to create a package from scratch. You’ll learn how to set up the directory structure, write the manifest, plan reusable operators, add deployable pipelines, and include runnable examples.
Create the package scaffold
Section titled “Create the package scaffold”Create a directory with the standard package layout:
Directoryacme/
Directorychangelog/ User-facing documentation of changes
- …
Directoryexamples/ Runnable snippets for users
- …
Directoryoperators/ Reusable building blocks for pipelines
- …
Directorypipelines/ Deployable pipelines
- …
Directorytests/ Integration tests
Directoryinputs/ Sample data for test pipelines
- …
- package.yaml Manifest: descriptive fields, metadata, contexts, and inputs
The tests/inputs/ directory holds sample data that the test harness makes
available via the TENZIR_INPUTS environment variable. Reference these files
from test pipelines using f"{env("TENZIR_INPUTS")}/filename.txt".
Add the package manifest
Section titled “Add the package manifest”The package.yaml file is the package manifest. It identifies the directory
as a package and contains descriptive fields, categories, external metadata,
context definitions, and input specifications.
Add descriptive metadata
Section titled “Add descriptive metadata”Start with the required and recommended metadata fields:
# The unique ID of the package. (required)id: acme
# The display name of the package and a path to an icon for the package.name: My Packagepackage_icon: https://example.com/icon.svg
# The display name of the package author and a path to a profile picture.author: Your Nameauthor_icon: https://github.com/yourusername.png
# A user-facing description of the package.description: | A brief description of what your package does and the use cases it supports. You can use **Markdown** formatting here.
# User-facing categories for the Tenzir Library.# Valid values: sources, destinations, mappings, contexts.categories: - sources - mappingsAdd external metadata
Section titled “Add external metadata”Use top-level categories for the Library grouping. Valid values are sources,
destinations, mappings, and contexts. Use the top-level metadata field
for data consumed by external tools. Tenzir accepts this field but does not
interpret its contents.
metadata: vendor: Acme source: https://github.com/acme/tenzir-packagesUnknown top-level keys outside the package schema fail validation. Put
non-engine package data under metadata instead.
Define inputs
Section titled “Define inputs”Inputs provide a templating mechanism that replaces variables with user-provided values during installation. This makes packages configurable without modifying source files.
inputs: refresh_interval: name: Refresh Interval description: How often the pipeline refreshes the data source. default: 1hReference inputs using {{ inputs.input-id }} syntax. See Configure inputs for the complete templating guide.
Plan package capabilities
Section titled “Plan package capabilities”A package can expose several capabilities at once. Treat user-defined operators as the reusable API, deployable pipelines as operational templates, examples as short usage snippets, and tests as the executable contract.
- Put reusable package capabilities under
operators/. - If the package maps to OCSF, expose a main mapper such as
acme::ocsf::mapthat accepts parsed source events, performs source-specific cleanup and shared OCSF setup, produces minimal OCSF, and dispatches to event-specific operators under a local namespace such asoperators/ocsf/events/. - Put complete workflows with an input and output under
pipelines/. Disable optional operational pipelines by default withdisabled: true. - Put focused snippets under
examples/so users can quickly try the package after installation. - Put deterministic tests under
tests/, including baselines for every public operator.
Add examples
Section titled “Add examples”The examples directory contains self-contained code snippets that demonstrate
how to use the package. These snippets appear in the Tenzir
Library and provide runnable TQL code that
users can execute after installing the package.
Create example files that showcase your package’s features:
// Demonstrate the primary use caseacme::fetchacme::transformhead 10For more complex scenarios, combine multiple operators and show how they work together:
// Show a more complex scenarioacme::fetchwhere severity == "high"acme::enrichpublish "alerts"Keep examples focused and self-contained. Each example should demonstrate a single concept or use case.
Define contexts
Section titled “Define contexts”If your package uses enrichment contexts, add a contexts key to the manifest.
See Add contexts for the full schema and
usage details.