Spark (spark v2.3.14)
View Source
Build powerful, extensible DSLs with exceptional developer experience
Spark is a framework for creating declarative domain-specific languages in Elixir. It transforms simple struct definitions into rich, extensible DSLs that come with autocomplete, documentation generation, and sophisticated tooling built right in.
Quick Example
Here's how you can build a data validator DSL with Spark:
defmodule MyApp.PersonValidator do
use MyLibrary.Validator
fields do
required [:name]
field :name, :string
field :email, :string do
check &String.contains?(&1, "@")
transform &String.trim/1
end
end
end
MyApp.PersonValidator.validate(%{name: "Zach", email: " foo@example.com "})
{:ok, %{name: "Zach", email: "foo@example.com"}}The DSL definition itself is clean and declarative:
@field %Spark.Dsl.Entity{
name: :field,
args: [:name, :type],
target: Field,
describe: "A field that is accepted by the validator",
schema: [
name: [type: :atom, required: true, doc: "The name of the field"],
type: [type: {:one_of, [:integer, :string]}, required: true, doc: "The type of the field"],
check: [type: {:fun, 1}, doc: "A function to validate the value"],
transform: [type: {:fun, 1}, doc: "A function to transform the value"]
]
}
@fields %Spark.Dsl.Section{
name: :fields,
entities: [@field],
describe: "Configure the fields that are supported and required"
}
use Spark.Dsl.Extension, sections: [@fields]What You Get Out of the Box
- 🔧 Extensible Architecture - Anyone can write extensions for your DSL, making it infinitely customizable
- 🧠 Smart Autocomplete - Built-in ElixirSense integration provides intelligent code completion and inline documentation in your editor
- 📚 Auto Documentation - Generate comprehensive documentation for your DSL automatically, including all options and usage examples
- ⚡ Developer Tools - Mix tasks for formatting, code generation, and
maintaining
locals_without_parensautomatically - 🔄 Compile-time Processing - Use transformers to modify DSL structure$ during compilation and verifiers to validate correctness
- 🎯 Type Safety - Rich schema validation ensures DSL usage is correct at compile time with helpful error messages
- 🔍 Introspection - Built-in tools to inspect and query DSL definitions programmatically at runtime
Installation
Add spark to your list of dependencies in mix.exs:
def deps do
[
{:spark, "~> 2.3"}
]
endGetting Started
The best way to get started is with our comprehensive tutorial that walks you through building a complete DSL from scratch:
📖 Get Started with Spark - Build a data validator DSL step by step
Quick Start Checklist
- Define your DSL structure using
Spark.Dsl.SectionandSpark.Dsl.Entity - Create your extension with
use Spark.Dsl.Extension - Build your DSL module that users will import
- Add transformers and verifiers for advanced behavior
- Generate helper functions with
Spark.InfoGenerator
Each step is covered in detail in the tutorial above.
Documentation
📚 Guides & Tutorials
- Get Started with Spark - Complete tutorial building a validator DSL
- Writing Extensions - Deep dive into extension development
- Setup Autocomplete - Configure editor integration
- Split Up Large DSLs - Organize complex DSL definitions
- Use Source Annotations - Leverage location tracking for better errors
🔧 API Reference
- HexDocs - Complete API documentation
- Core Modules:
Spark.Dsl.Extension,Spark.Dsl.Entity,Spark.Dsl.Section - Advanced Features:
Spark.Dsl.Transformer,Spark.Dsl.Verifier,Spark.InfoGenerator
Production Ready
Spark is battle-tested and powers all DSLs in the Ash Framework, handling complex real-world applications with thousands of DSL definitions. Whether you're building configuration DSLs, workflow orchestrators, or domain-specific languages for your business logic, Spark provides the foundation for production-grade solutions.
Links
Summary
Functions
Returns the extensions a given DSL uses
Returns true if the module implements the specified behavior
Returns the configured otp_app of a given DSL instance
Returns all modules that implement the specified behaviour for a given otp_app.
Functions
Returns the extensions a given DSL uses
Returns true if the module implements the specified behavior
Returns the configured otp_app of a given DSL instance
Returns all modules that implement the specified behaviour for a given otp_app.
Should only be called at runtime, not at compile time, as it will have inconsistent results at compile time.