Spry LogoOpsfolio
Contributing and Support

Frequently Asked Questions

Common questions and answers for setting up, using, and troubleshooting Spry

This FAQ covers common questions and pitfalls when setting up and using Spry, a lightweight TypeScript ecosystem that treats Markdown as executable, composable workflows.


What is Spry?

Spry is an ecosystem of TypeScript libraries that treat Markdown as a programmable medium — instead of just documentation, .md files become executable workflows. Spry interprets fenced code blocks and directives as executable units with dependencies, metadata, and outputs.

What can I use Spry for?

  • DevOps Runbooks - Executable operations documentation
  • Data Pipelines - ETL workflows in Markdown
  • Compliance Automation - Policy-as-code with evidence generation
  • SQLPage Apps - SQL-based web dashboards
  • Build Automation - Task orchestration

How is Spry different from Make/Task/Just?

Spry documents are also valid Markdown. You can read them on GitHub, in VS Code, or any Markdown viewer. The documentation is the automation, not separate files.


Installation & Setup

What are the prerequisites?

Spry runs using Deno (type-safe TypeScript runtime), so ensure you have:

deno --version

What are the system requirements?

  • Deno 2.5+ (required)
  • Any OS: Linux, macOS, Windows
  • No other dependencies

How do I fix errors that occur while upgrading Spry to the latest version using Homebrew?

If you encounter any errors while upgrading Spry to the latest version using Homebrew, follow these steps to perform a clean reinstall:

  1. If a specific version is installed and linked (for example, v1.0.2), uninstall it first:

    brew uninstall spry@1.0.2
  2. Uninstall Spry completely:

    brew uninstall spry
  3. Remove the old Homebrew tap:

    brew untap programmablemd/homebrew-packages
  4. Reinstall Spry from the official tap:

    brew install programmablemd/packages/spry
  5. Verify the installation:

    spry --version
    spry --help

How do I bootstrap a new Spry project?

Use the built-in CLI initializer:

# Create or navigate to an empty project directory
cd <your-project>

# Bootstrap a Spry + SQLPage project using 
./spry.ts sp init


# Verify
./spry.ts help

This generates:

  • spry.ts — Spry CLI runner
  • Spryfile.md — executable Markdown workflow
  • SQLPage config files (if applicable)

Why am I seeing permission errors when running Spry?

Spry may need access to file systems, network, and subprocesses. Use Deno's permission flags -A (allow all), or more targeted flags:

deno run -A spry.ts <command>

For production, tighten permissions as needed.

Do I need to know TypeScript?

No. Basic Spry usage only requires Markdown and shell scripting. TypeScript is only needed for extending Spry or using the programmatic API.

Can I use Spry with Node.js?

Spry is built on Deno, not Node.js. However, your Spryfiles can execute any commands, including Node.js scripts.

Is there a Docker image?

Not officially, but you can create one:

FROM denoland/deno:2.5.0
RUN deno install -A -n spry https://raw.githubusercontent.com/programmablemd/spry/main/bin/spry.ts

Writing Spry Workflows

What file extension should I use?

Use .md for Spryfiles. Common naming conventions:

  • Spryfile.md - Main project file
  • runbook.md - Operational runbook
  • deploy.md - Deployment workflow

What goes into Spryfile.md?

Spry treats every fenced code block as an executable cell. Code blocks should have a language tag + valid Spry directives:

```sql {.store-result}
SELECT * FROM users;
```

If code blocks lack proper language or directive attributes, execution may skip them.

Can I have multiple Spryfiles?

Yes. You can organize complex projects across multiple files and run them independently.

Are there limits on file size?

No hard limits, but large files may impact performance. Consider splitting files over 1000 lines.

How do I debug why a block didn't run?

  • Check that the fence has a supported language tag and any required attributes (.store-result, .task, etc.).
  • Run Spry with verbose or watch mode to see logs.
  • Validate there are no invalid dependencies between tasks.

Tasks

What languages can I execute?

Any language that can run as a command:

  • Shell (bash, sh, zsh)
  • Python
  • Ruby
  • Node.js
  • Go
  • Rust
  • Any CLI tool

How do I pass arguments to tasks?

Currently, arguments are set via environment variables:

MY_ARG="value" spry rb run file.md

In the task:

echo "Argument: $MY_ARG"

Can tasks run in parallel?

Currently, tasks run sequentially in topological order. Tasks without dependencies between them could run in parallel in future versions.

How do I skip a task?

Use conditional logic in the task itself:

```bash conditional-task
if [ "$SKIP_TASK" = "true" ]; then
    echo "Skipping"
    exit 0
fi
# Rest of task...
```

What happens if a task fails?

By default, execution stops on the first failure. Use --continue-on-error to continue, or add --continue-on-error to specific tasks.


Dependencies

How are dependencies resolved?

Spry builds a DAG (Directed Acyclic Graph) from --dep declarations and executes tasks in topological order.

Can I have optional dependencies?

Not directly. Use conditional logic in tasks to handle optional behavior.

What if I have circular dependencies?

Spry detects and reports circular dependencies. You must remove one dependency to break the cycle.


Development & Workflow

How can I watch for changes and rebuild automatically?

Use Spry's watch mode:

./spry.ts spc \
  --fs dev-src.auto \
  --destroy-first \
  --conf sqlpage/sqlpage.json \
  --watch \
  --with-sqlpage

This monitors changes and rebuilds on update.

How do I package my Spry workflows for production?

You can bundle into a single SQLite or PostgreSQL database:

./spry.ts spc --package --conf sqlpage/sqlpage.json | sqlite3 spry-sqlpage.sqlite.db

Or pipe to a Postgres instance:

./spry.ts spc --package --conf sqlpage/sqlpage.json | psql

Production outputs include compiled SQLPage assets and workflow metadata.


SQLPage

What databases are supported?

  • SQLite
  • PostgreSQL
  • MySQL
  • Microsoft SQL Server

Can I use SQLPage without a database?

SQLite in-memory mode works: sqlite://:memory:

How do I deploy SQLPage apps?

  1. Build: ./spry.ts sp spc Spryfile.md --fs
  2. Deploy the generated SQL files with SQLPage
  3. See SQLPage Dashboards

SQLPage Integration Issues

  • Ensure sqlpage/sqlpage.json exists and is configured correctly.
  • Check that dev-src.auto/ is generated during development.
  • Verify database connection strings are correct.

Configuration

Where does configuration go?

  1. Document frontmatter - In the Spryfile
  2. Environment variables - SPRY_*
  3. Command-line flags - Override at runtime

How do I use secrets?

Never put secrets in Spryfiles. Use environment variables:

---
api_key: ${env.API_KEY}
---

Can I share configuration between files?

Use environment variables or include common configuration via the include directive.


Common Issues

Installation Problems

  • Ensure Deno is installed and up-to-date.
  • Check you are in the correct directory when initializing.
  • If Spry CLI doesn't run, verify your shebang (./spry.ts) and executable permission.

Spryfile.md Won't Execute

  • Confirm language tags and Spry attributes are valid.
  • Some tools strip attributes — ensure your editor preserves them.
  • Validate there are no syntax errors in Markdown.

Performance Issues

Large workflows can slow execution:

  • Split into smaller, independent Spry files.
  • Use task dependencies efficiently.
  • Monitor with --watch during active development.

Comparison

Spry vs Jupyter Notebooks

FeatureSpryJupyter
FormatPlain MarkdownJSON
ExecutionCLI/CIInteractive
Version controlExcellentChallenging
LanguagesAnyKernel-based

Spry vs Ansible/Terraform

FeatureSpryAnsible/Terraform
PurposeDocumentation + AutomationInfrastructure automation
FormatMarkdownYAML/HCL
Learning curveLowMedium-High
State managementNoneBuilt-in

Spry complements rather than replaces infrastructure tools.

Spry vs GitHub Actions

FeatureSpryActions
ExecutionLocal or CIGitHub only
FormatMarkdownYAML
PortabilityAny environmentGitHub
DocumentationNativeSeparate

You can use Spry within GitHub Actions.


Extending

Can I create plugins?

Yes! See Creating Extensions for:

  • Custom remark plugins
  • Custom edge rules
  • Custom projections
  • Custom executors

Is there a plugin registry?

Not yet. Share plugins via npm/deno.land/x or GitHub.

Can I use Spry as a library?

Yes. See Programmatic API.


Community

Where can I get help?

How can I contribute?

See Contributing for:

  • Bug reports
  • Feature requests
  • Code contributions
  • Documentation improvements

Is Spry production-ready?

Spry is actively developed and used in production. Check the GitHub issues for known limitations.


Tips & Best Practices

  • Prefer explicit directives and metadata in code blocks for clarity.
  • Use task naming and dependencies to structure workflows cleanly.
  • When possible, keep workflows small and composable.
  • Test blocks independently before integrating into larger Spry projects.

Quick Reference

TaskDeveloper CommandExecutable Package Command
Initialize project./spry.ts sp initspry sp init
Show help./spry.ts helpspry help
Watch mode./spry.ts sp spc --watchspry sp spc --watch
Package for production./spry.ts spc --packagespry sp spc --package

Still have questions? Open a discussion.

How is this guide?

Last updated on

On this page

What is Spry?
What can I use Spry for?
How is Spry different from Make/Task/Just?
Installation & Setup
What are the prerequisites?
What are the system requirements?
How do I fix errors that occur while upgrading Spry to the latest version using Homebrew?
How do I bootstrap a new Spry project?
Why am I seeing permission errors when running Spry?
Do I need to know TypeScript?
Can I use Spry with Node.js?
Is there a Docker image?
Writing Spry Workflows
What file extension should I use?
What goes into Spryfile.md?
Can I have multiple Spryfiles?
Are there limits on file size?
How do I debug why a block didn't run?
Tasks
What languages can I execute?
How do I pass arguments to tasks?
Can tasks run in parallel?
How do I skip a task?
What happens if a task fails?
Dependencies
How are dependencies resolved?
Can I have optional dependencies?
What if I have circular dependencies?
Development & Workflow
How can I watch for changes and rebuild automatically?
How do I package my Spry workflows for production?
SQLPage
What databases are supported?
Can I use SQLPage without a database?
How do I deploy SQLPage apps?
SQLPage Integration Issues
Configuration
Where does configuration go?
How do I use secrets?
Can I share configuration between files?
Common Issues
Installation Problems
Spryfile.md Won't Execute
Performance Issues
Comparison
Spry vs Jupyter Notebooks
Spry vs Ansible/Terraform
Spry vs GitHub Actions
Extending
Can I create plugins?
Is there a plugin registry?
Can I use Spry as a library?
Community
Where can I get help?
How can I contribute?
Is Spry production-ready?
Tips & Best Practices
Quick Reference