# Ferret v2: A Declarative Language and Go Runtime for Structured Data Automation

> Ferret v2 is an alpha-stage embedded language and Go runtime for querying, transforming, and synchronizing structured data. This review covers its architecture, migration path from v1, and the trade-offs you should weigh before adopting it.

**MontFerret/ferret** — Declarative data automation language and Go runtime for structured extraction workflows.

- Repository: https://github.com/MontFerret/ferret
- Website: https://www.ferretlang.org
- Stars: 6,014 · Forks: 325
- Language: Go
- License: Apache-2.0
- Published: 2026-08-23 · Updated: 2026-08-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/montferret-ferret

## What Ferret v2 Actually Solves

Ferret v2 is a declarative-first, expression-oriented language and runtime for data automation. It targets developers who need to query, transform, and synchronize structured data from multiple sources, such as browsers, APIs, databases, and custom documents, without writing imperative glue code for each one. The project describes FQL as deliberately focused rather than a general-purpose scripting language. That focus is the core value: you get a unified query model and a runtime that can execute the same logical operations across heterogeneous data sources. The primary audience is Go developers embedding the runtime into their applications, not end users writing standalone scripts. The v2 branch is a rewrite, and the README is explicit that it is in alpha, so early adopters should expect API changes.

## The Execution Model: Engine, Plan, Session, Run

The v2 architecture is visible in the native API flow: Engine, compile query, create session, run. You start with an engine instance, compile a query string into a plan, then create a session from that plan, and finally run the session with a context. The separation between compilation and execution is deliberate. Compiled plans are reusable, which means you can compile once and run multiple times with different sessions. Sessions provide isolated execution environments, so state does not leak between runs. The README also mentions a bytecode VM and portable programs for efficient repeated execution and precompiled artifacts. That is a meaningful design choice: it moves Ferret away from a purely interpreted AST walker toward a compiled model, which should improve performance for repeated executions, though the alpha status means no benchmarks are provided.

## Capability-Based Host Values and Extensibility

One of the more interesting mechanisms is capability-based host values. The runtime lets the embedding application expose objects, resources, and external systems to FQL programs, but only those the host explicitly grants. This is a security and isolation feature: an FQL program can only touch what the host has decided to hand it. The README lists namespaced functions, modules, hooks, and custom value types as extension points. That means you are not stuck with a fixed standard library; you can add your own namespaced operations. The trade-off is that you must design and expose those capabilities yourself, which adds integration work. The documentation also mentions managed resource lifecycle for files, connections, cursors, and streams, which suggests the runtime handles cleanup of host resources, a useful property for long-running sessions.

## Getting Started with the Native v2 API

The README gives a minimal Go example that compiles and runs a query. The setup is straightforward: add the module with go get github.com/MontFerret/ferret/v2@latest, then create an engine, compile a query string, create a session, and run it. The example uses engine.New(), eng.Compile(), plan.NewSession(), and session.Run(ctx). The result is available as result.Content. This is a clean API surface, but note that the README does not show how to pass input data or custom capabilities into a query. You will need to consult the docs for that. The example is minimal, but it demonstrates the core flow without external dependencies, which is a good sign for embeddability.

## Migration from v1: The compat Module and the ferret migrate Command

For existing v1 users, Ferret v2 offers a compatibility module and a migration tool. The recommended path is two-stage: first migrate to the v2 compatibility API, then incrementally to the native v2 API. The ferret migrate command, part of the separate MontFerret/cli repository, rewrites documented v1 imports to v2 compatibility packages, updates go.mod and go.sum, and formats changed Go files. It leaves generated, vendored, and nested-module files untouched. The command has a --dry-run flag to list changes and a --print flag to show a unified diff without applying. Importantly, the README warns that the command does not convert application logic to the native v2 API, and running it again on an already-migrated project is a no-op. That is a clear limitation: the migration tool is mechanical, not semantic. You still have to manually port your logic and any unsupported v1 packages.

## Alpha Status and the Wrong Tool Cases

The most obvious limitation is that Ferret v2 is in alpha. The README states that some APIs and language features may change before the stable release. That means production adoption carries a real risk of breaking changes. The wrong tool cases are clear: if you need a stable, long-term supported language, or if your automation logic is simple enough to express in a few lines of Python or shell, Ferret v2 is overkill. Its declarative core and bytecode VM add complexity that is only justified when you have repeated, structured extraction workflows across multiple sources. Also, because it is embeddable rather than a standalone tool, you need to write Go code to host it. If you are not a Go shop, this is not the right fit. The README does not mention any web UI or standalone server; those are separate projects (CLI, lab, worker) that are not covered in this repository.

## Alternatives: Comparing Approach and Fit

A direct alternative is writing your own extraction logic in Go with libraries like goquery for HTML parsing or sqlx for database access. That approach is imperative: you write loops, conditionals, and error handling for each source. Ferret v2 instead offers a declarative query language that unifies those operations. The difference is in abstraction level: with goquery you control every step, while with FQL you describe the desired result and let the runtime execute. Another alternative is using a general-purpose language like Python with BeautifulSoup or Scrapy. Those are mature and stable, but they are not embeddable in Go and do not provide a capability-based security model. Ferret v2's advantage is its integration with Go and its explicit resource management, but those benefits only matter if you are building a Go application that needs a query language, not if you just want to scrape a few pages.

## Licence and Maintenance Cost

Ferret is licensed under Apache-2.0, which permits commercial use, modification, and redistribution with attribution, and it does not require you to open-source your own code. That is a permissive licence and a low barrier for adoption. The maintenance cost is harder to gauge. The repository is actively developed, with alpha releases every few days in the provided data (v2.0.0-alpha.48, alpha.49, alpha.50 within a week). That pace signals rapid change, which is good for progress but bad for stability. You will need to track releases and adapt to API changes. The README mentions a community and sponsors, but no formal support guarantees. For a production system, you should budget time for monitoring releases and updating your code, or wait for a stable release. The alpha status alone is a maintenance red flag for critical workflows.

## Conclusion

Adopt Ferret v2 if you need an embeddable, capability-based language for automating structured data workflows across browsers, APIs, and databases, and you can tolerate alpha instability. Skip it if you need a stable, production-ready tool today or prefer a general-purpose scripting language. Before committing, verify that the v2 API and language features cover your specific extraction patterns, and check the migration tool's output on a real codebase with the --dry-run flag.

## FAQ

### What is Ferret v2?

A declarative-first, expression-oriented language and Go runtime for data automation, combining querying, transformation, synchronization and structured results with host-defined values. It keeps a declarative core and adds domain-oriented orchestration plus constrained mutable state, and the readme describes it as deliberately focused rather than a general-purpose scripting language.

### How do I add Ferret v2 to a Go project?

Ask for the second major version explicitly at its latest. Then choose an entry point: the native API for new projects, or the compatibility module as a first step for existing first-version integrations. Applications built against the project's separate API package use the universal adapter instead, which either creates and owns an engine or wraps one that already exists.

### How do I migrate an existing Ferret v1 application to v2?

In two stages. First run the migrate command, which offers a dry run listing the files it would change, a print mode showing a unified diff, and an apply mode; it rewrites documented imports, updates the module files, formats what it changed, leaves generated, vendored and nested-module files alone, and reports anything it cannot rewrite as manual follow-up. It does not convert application logic or migrate drivers, and rerunning it changes nothing.

### Is Ferret v2 ready for production use?

The readme says it is currently in active development, that alpha releases are intended for early adopters, experimentation and feedback, and that some APIs and language features may still change before the stable release. The three most recent releases are all second-version alpha builds, and the stable first version is on a separate branch of the same repository.

### What can a Ferret program actually do?

The feature list pairs querying, transformation, synchronisation and automation of structured data with one unified query model across browsers, APIs, databases, documents and custom sources. Extensibility comes through namespaced functions, modules, hooks and custom value types, and the host application decides which of those a program may use.

## Sources

- [Official documentation](https://www.ferretlang.org)
- [Official README](https://github.com/MontFerret/ferret#readme)
- [Project repository](https://github.com/MontFerret/ferret)
- [Release notes](https://github.com/MontFerret/ferret/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/montferret-ferret
