Extending JetBrains MPS: Plugins, Generators, and Custom Editors

JetBrains MPS vs. Traditional IDEs: When to Use a Language WorkbenchProgramming tools sit on a spectrum from text-oriented editors and integrated development environments (IDEs) to language-oriented workbenches. Traditional IDEs (IntelliJ IDEA, Visual Studio, Eclipse, VS Code) excel at editing, navigating, compiling, and debugging programs written in general-purpose languages (Java, C#, JavaScript, etc.). Language workbenches such as JetBrains MPS (Meta Programming System) take a different approach: they make languages first-class artifacts you can design, extend, and compose. This article compares JetBrains MPS with traditional IDEs, explains where a language workbench becomes the better choice, and offers practical guidance for teams considering MPS.


Executive summary — the short answers

  • JetBrains MPS is a language workbench for creating and using domain-specific languages (DSLs).
  • Traditional IDEs are best when you work primarily with mainstream textual programming languages and existing toolchains.
  • Use a language workbench when your domain benefits from custom syntax/semantics, model-driven development, or powerful, structure-aware editors that eliminate parsing ambiguity.

What JetBrains MPS is (and what it isn’t)

JetBrains MPS is a projectional, model-based language workbench. Its core ideas:

  • Languages are defined as structured models (ASTs) rather than plain text.
  • Projectional editing displays a concrete syntax that’s edited directly into the model (no text parsing).
  • You can define custom editors, type systems, constraints, generators (transformations), and integrations.
  • Languages and language extensions are first-class artifacts and can be composed to build richer languages or DSLs.

What MPS is not:

  • It’s not just another text editor plugin. MPS replaces parsing with structure-aware editing.
  • It’s not a general-purpose IDE replacement for most teams — unless you have clear DSL needs.

How projectional editing changes the game

Traditional editors rely on textual source code and parsers to build syntax trees. Projectional editing (MPS’s approach) directly manipulates syntax trees and projects them as a visual or textual representation. Key consequences:

  • No parse errors from incomplete or ambiguous text — the editor always produces a valid model.
  • You can freely mix notation styles (text, tables, diagrams, inline UI elements).
  • Refactorings and semantic checks become more precise because the editor manipulates the underlying model directly.
  • Implementing non-context-free notations or multiple overlapping syntaxes is simpler.

Trade-offs:

  • Editing experience can initially feel unfamiliar; some keyboard flows from plain-text editing may not map 1:1.
  • Diffing and merging textual files require special handling or serialization to text formats.
  • Tooling ecosystem (linters, formatters, existing plugins) may not directly apply.

Traditional IDE strengths

Traditional IDEs remain dominant for many reasons:

  • Mature ecosystems and large plugin marketplaces.
  • Excellent support for mainstream languages: syntax highlighting, autocompletion, refactoring, debugging, build tooling.
  • Familiar, efficient text-editing workflows for developers.
  • Seamless integration with version control systems using text diffs and merges.
  • Better fit for teams relying on established compilers, build pipelines, and continuous integration.

When to choose JetBrains MPS

Consider MPS when one or more of these apply:

  1. Domain complexity calls for domain-specific languages (DSLs)

    • Your domain has rich, specific concepts that are awkward or verbose in a general-purpose language.
    • DSLs reduce boilerplate and capture intent more directly (e.g., telecom protocols, financial products, product configuration).
  2. You need precise, model-driven tooling

    • You want type systems, constraints, validation rules, and generators tightly coupled with language constructs.
    • You need to produce multiple artifacts (code, configs, docs) from a single high-level model.
  3. Notation matters beyond plain text

    • You want to mix textual, tabular, or graphical notations, or embed UI widgets inside code.
    • You require concrete syntaxes that are ambiguous or impossible to parse reliably.
  4. Language composition and extensibility are strategic

    • Multiple teams need to extend a base language with new constructs, and composition should be safe and modular.
    • You want to create a family of DSLs with shared semantics and reuse.
  5. You value correctness over standard text workflows

    • Ensuring models are always valid is more important than line-based text editing or merge convenience.

Concrete examples where MPS has been used effectively:

  • Product configuration languages where domain experts define rules readable to non-developers.
  • Embedded systems or hardware description DSLs with precise constraints.
  • Code generators that output platform-specific code from high-level domain models.
  • Educational tools and research where exploring new notations and semantics is the goal.

When to stick with a traditional IDE

Do not adopt MPS if these describe your situation:

  • You’re primarily writing application code in mainstream languages (Java, Python, JavaScript) and rely heavily on existing libraries, debugging, and build tooling.
  • Your team values standard text-based workflows, simple Git diffs, and the broad ecosystem of linters, formatters, and language servers.
  • The learning curve and maintenance burden for DSLs outweigh potential productivity gains.
  • Integration with third-party tools that expect text inputs is critical and hard to adapt.

Costs and practical trade-offs

  • Learning curve: Developers and domain experts must learn MPS concepts (projectional editing, language definition).
  • Tooling and ecosystem: Smaller ecosystem than mainstream IDEs; fewer ready-made plugins.
  • Version control: Model serialization and diffs require attention. Projects typically use textual serialization options or custom workflows.
  • Maintenance: Language maintenance is ongoing — changes to DSLs can require migration and careful change management.
  • Upfront investment: Creating a well-designed DSL takes design time. ROI appears when many users or repeated tasks benefit.

Integration patterns and workflows

  • Code generation: Use MPS generators to emit Java/C/C++/etc. that compiles in standard toolchains; developers can still use traditional IDEs for generated artifacts.
  • Hybrid workflows: Keep business logic or platform-facing code in a traditional language and use DSLs for configuration/specifications that generate that code.
  • Round-tripping: Design serialization so artifacts can be exported to readable text for code reviews or version control when needed.
  • CI/CD: Integrate MPS-based builds into automated pipelines by running generation and tests as part of builds.

Developer experience — what changes day to day

  • Editing: Structure-aware completion and no parse errors; certain free-form edits may feel more constrained.
  • Refactoring: More precise, less brittle refactorings because operations manipulate the model.
  • Debugging: You still rely on target language debuggers for generated code; debugging at the model level needs custom tooling or traceability.
  • Collaboration: Communicate DSL changes as API changes — training and documentation for team members who use the DSL is necessary.

Tips for a successful MPS adoption

  • Start small: Prototype a focused DSL solving a concrete pain point (e.g., build scripts, configuration, domain rules).
  • Measure ROI: Track time saved, defect reduction, and maintenance effort before scaling.
  • Provide clear documentation and examples for the DSL and editor interactions.
  • Keep generated artifacts readable and well-documented to aid debugging.
  • Use textual or VCS-friendly serialization formats where possible, and define migration strategies.
  • Encourage incremental adoption: let some teams or components use MPS while others continue in traditional IDEs.

Example scenario: a good fit

A company building configurable IoT-device firmware has dozens of product variants. Product configuration, hardware mappings, and deployment rules are repetitive and error-prone in plain Java. The team designs an MPS DSL that captures device features, constraints, and deployment profiles; generators produce optimized C code and build scripts. Domain experts can read and verify high-level specs; engineers maintain generators. Results: fewer configuration bugs, faster new-product ramp-up, and a single source of truth.


Example scenario: a poor fit

A web app team heavily reliant on JavaScript/TypeScript libraries, npm, and quick iteration cycles gains little from MPS. The overhead of DSL design and model-based editing outweighs any marginal benefits; traditional IDEs with mature extensions remain faster and cheaper.


Conclusion

JetBrains MPS and traditional IDEs address different problems. Traditional IDEs are optimized for text-based general-purpose programming, mature ecosystems, and familiar developer workflows. JetBrains MPS is optimized for creating, composing, and using domain-specific languages with model-centric correctness and flexible notations.

Use MPS when your domain demands specialized languages, model-driven correctness, or notations that can’t be handled well by text-based tools. Stick with traditional IDEs when you need broad ecosystem support, standard textual workflows, and minimal tooling overhead.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *