Domain-specific language (DSL)

A domain-specific language (DSL) is a programming or markup language designed for a narrow, specialized domain, in contrast to a general-purpose language such as JavaScript or SQL that can express programs across a wide range of problem areas. By restricting their scope, DSLs can offer concise, readable syntax that closely mirrors the concepts and vocabulary of the domain they serve, making them accessible to domain experts who may not be professional programmers.

DSLs come in two broad categories. An external DSL has its own dedicated syntax and parser – Gherkin, used in behavior-driven development to specify acceptance criteria in a Given-When-Then format, is a well-known example. An internal or embedded DSL is implemented within a general-purpose host language, leveraging that language’s syntax and tooling to create a mini-language. Reactive programming frameworks and fluent builder APIs are common examples.

DSLs are widespread in software tooling. Diagrams-as-code tools such as Structurizr define DSLs for describing software architecture models. Containerization systems use DSLs like the Dockerfile syntax to declare container image build instructions. Modeling tools frequently expose their own DSLs for describing domain structures, BPMN processes, or other model types. The Structurizr DSL, for instance, lets architects define C4 model diagrams as plain text that can be version-controlled alongside application code.

The trade-off when adopting a DSL is between expressiveness and learning cost. A well-designed DSL can make domain-specific tasks dramatically more concise and clear, but each new DSL adds a syntax and mental model that users must learn. DSLs that grow beyond their intended scope risk accreting general-purpose features and becoming harder to use than the host languages they were meant to simplify – a phenomenon sometimes called the inner-platform effect.