OOLOI.ORG
Menu

OOLOI

An Organism Evolved.

OVERVIEW

DOCUMENTATION

NEWSLETTER

Taking Stock at Two Years

9/7/2026

2 Comments

 
Creating a wind quintet with score and parts in Ooloi.
​Then adding doublings. No dialogs.

Two years ago today, on 9 July 2024, the first commit to Ooloi went in. Time to take stock.

There's no music on screen. Two years in, and still not one printed note. No noteheads. No beams. No slurs. No page of music. All true, all planned, and all completely beside the point.

Why? A notehead drawn in the first year would've been a comfort object, not evidence. So the visible surface stayed sparse on purpose while the real work went on underneath it. The absence of staves was never the interesting fact about this project. It was the cost of getting the interesting facts right, and this anniversary is the point at which they start becoming visible.

This isn't an eccentric way to build notation software. It's how the serious ones are built, and the record is consistent. Sibelius took its two founders about seven years before the first release in 1993. MuseScore was carved out of a sequencer in 2002 and did not reach a stable 1.0 until 2011. Dorico, built by most of the old Sibelius team after they were let go, took close to four years and shipped its first version deliberately slow and incomplete, engine and engraving model first; the field judged the decision sound. Three programs, three decades, open source and commercial alike, and in every case the foundational years came before anything a user would recognise as finished.

The counter-example proves the same point from the other side. Finale shipped fast in 1988, did more than anything before it, and became the industry standard for a generation. It was also, by wide agreement, punishing to use, and when its owners finally discontinued it in 2024 they said plainly that decades of accumulated code had made each new version harder to deliver and worth less. Feature piled on feature until the architecture could no longer move. That's the ceiling a notation program hits when the surface is built before the foundations are right.

Two years isn't a long time to spend getting the foundations of a fifty-year program right, and I've never regarded it as a delay.

Now, the bet on which Ooloi is built is functional programming. Music notation is a genuinely hard computer science problem wearing a friendly costume, and Clojure's properties looked to me like the right machinery for the parts of it that commercial programs have learned to manage rather than solve. Ooloi is my first Clojure project, though not my first Lisp by a long way, so the syntax was familiar ground; an old hand picks up a new dialect quickly.

The deeper reorientation was immutability. Fully embracing immutable data structures, rather than merely tolerating them, changed how I thought about the whole domain, and almost everything architecturally distinctive about Ooloi fell out of that one shift. Undo, collaboration across machines, full use of multi-core parallelism, pervasive structural sharing: none of these is a feature bolted onto mutable objects. Each is a consequence of representing musical facts as immutable values. Learning to think that way was the real work of the first stretch.

The harder part was psychological. A screenshot of notation would've been reassuring, and I could've produced something theatrical early on if theatre had been the goal. I grew up around theatre. I know a backdrop when I see one. I also know there's never a wall behind it.

So the project spent a long time with most of its real work below the surface. The documentation was public, the ADRs were public, the blog was public, but the evidence still required reading. And the focus on the yet invisible might have given the impression that progress had been slow. So I drew up a list of what's been completed over the past two years.

I expected it to be useful. I did not expect it to be quite so long.

That surprised me, which is perhaps the point of doing the accounting at all. Daily work doesn't feel like accumulation. It feels like the next ticket, the next invariant, the next small refusal to leave a problem in a shape that'll charge interest later. Only when the pieces sit next to each other does the scale become visible:
​​
  • Core musical model: Pieces, musicians, instruments, staves, measures, voices, rhythmic items, attachments, traits, hierarchy, and the basic vocabulary for representing musical facts.
  • VPD addressing: Vector path descriptors, giving operations precise structural addresses inside a piece.
  • STM coordination: Transactional backend state, with Clojure STM used as the coordination model for musical mutation.
  • Timewalking: Temporal traversal of nested score structure, including the transducer-based breakthrough that made the score streamable in musical order.
  • Pitch representation: Exact spelling, rational arithmetic, transposition machinery, and round-trip integrity.
  • Time signatures: Ordinary, additive, mixed-unit, fractional, irrational, historical, and descriptor-preserving signatures.
  • Key signatures: Standard modes, keyless notation, custom signatures, per-octave variants, and microtonal systems.
  • Remembered alterations: Deterministic accidental handling built on pitch, time, key context, and traversal.
  • Measure distribution: Formal specification of measure distribution as a Knuth-Plass-style optimisation problem.
  • Persistence and compression: Serialisation, structural sharing, hash-consing, and the 50,000-note compression test.
  • gRPC API: Generated method exposure, Protocol Buffers conversion, streaming, bounded queues, events, and the unified value transport.
  • Server statistics: HTTP metrics, health endpoints, and the monitoring machinery used to validate server behaviour. Grafana and Prometheus support.
  • TLS and transport hardening: Secure transport foundations, connection handling, shutdown correctness, friendlier errors, and combined-app collaboration TLS.
  • Reference-passing transport: Near-zero-overhead in-process calls by removing the Clojure-to-protobuf conversion path inside the desktop app.
  • Integrant system architecture: Component lifecycle, dependency wiring, startup, shutdown, and the shared/backend/frontend division.
  • Frontend event architecture: Event bus, backend event router, category batching, wildcard subscription, invalidation routing, and JavaFX-thread discipline.
  • Backend-authoritative rendering design: Terminal frontend execution, paintlist boundary, cache hierarchy, and backend ownership of musical layout decisions.
  • Localisation: PO-file workflow, strict translation-key discipline, canonical UK English, runtime locale switching, build-time checks, and 22 bundled locales: Czech, Danish, German, Greek, UK English, US English, Spanish, Finnish, French, Hungarian, Icelandic, Italian, Japanese, Korean, Norwegian Bokmål, Dutch, Polish, Brazilian Portuguese, European Portuguese, Swedish, Ukrainian, and Simplified Chinese.
  • Frontend settings: Persistent application settings, registry-driven defaults, validation, generated Settings window, and reactive updates.
  • Window lifecycle: Declarative window opening, persistent geometry, fade behaviour, modal gating, and centralised stage management.
  • UI styling: Semantic styles, no hardcoded colour seepage, custom cljfx components, and Java interop confined to boundary files.
  • Notifications and chrome: Splash screen, platform menus, notification overlay, menu-bar host, About window, settings UI, and orderly shutdown.
  • Frontend undo and redo: Local undo history for application settings, integrated into the same menu surface as backend undo.
  • Backend undo and redo: Resource-level undo manager, coordinated history, localised descriptions, frontend routing, clock-offset adjustment, and cross-client undo.
  • Instrument Library: Real instrument and staff records, editing, validation, persistence, conflict retry, drag-and-drop, deletion tombstones, ordering, multilingual contents, and a complete populated default library.
  • Font management: Bundled SMuFL fonts, associated text fonts, font registry, and glyph-selection architecture.
  • Transaction-driven distributed updates: The whole update model. A change is a transaction against authoritative backend state; committing it names what's now stale, and every subscribed client, on the same machine or across the network, refetches the canonical structure and replaces its view. No deltas, no merge logic, no distributed-specific code paths. Collaboration is not a separate engine; it falls out of this for free.
  • ​Collaboration architecture: Dual-server model, local and network transports sharing backend state, frontend transport switching, host and guest roles, connection UI, and shared resource editing.
  • Two-laptop proof: Guest edit, host observation, host undo of the guest's change, propagation back to the guest; and, at the two-year mark, musicians created and rearranged in a shared piece window on one machine and appearing on another.
  • Post-demo hardening: Collaboration menu enablement, backend-switch undo-cache invalidation, standalone backend wiring, collaboration palette behaviour, anchor-first selection, modal menu gating, TLS routing, friendly errors, and headless test mode.
  • Platform support: macOS Apple Silicon, Windows x86_64, Linux x86_64, native bundles, Windows application build, and an explicit platform policy.
  • Documentation: ADRs, guides, development log, reading path, and Librarian, built as part of the system's survival machinery.
  • Test infrastructure: Shared, backend, and frontend tests, now around 24,400 passing cases.
  • Piece Window: Structural entity identity and cloning, opaque backend filesystem navigation, a component-owned piece-manager store, a custom Open/Save picker that never sees paths, a complete piece file menu (New, Open, Save, Save As, Close) with typed and translated failure messages, transport-blind file commands that work unchanged in a collaboration, deterministic backend close-on-last-release, and a piece window that's now a live view of authoritative backend state, updating across every subscribed client on any structural change.

During daily work, a subsystem closes and vanishes from attention. That's partly the method: finish something completely enough that it stops sharing the desk. The Instrument Library no longer asks to be designed. Localisation no longer asks to be invented, and the interface already speaks twenty-two locales. Undo no longer waits behind every future feature (with a small knife). Transport no longer converts itself through protobuf in-process for no reason. Window lifecycle no longer belongs to individual windows. Each closed subsystem removes one more thing from the cognitive field.

The list makes visible what the surface hid. Ooloi hasn't spent two years waiting to become a notation program. It's spent two years removing the taxes a notation program would otherwise pay forever.

This is also where the unusual working conditions matter. I've been ... unburdened by people. That sounds harsher than I mean it, though perhaps not by much. Not unburdened by readers, musicians, criticism or conversation, which have all mattered, but by the organisational forms that force software to explain itself before it has finished thinking. No investors, no release calendar, no committee, no inherited user base demanding that a workaround stay sacred because muscle memory has mistaken it for design.

A team would have made some things faster and some things impossible, or at least premature. There's a stage in a project like this where the architecture has to be held whole in one mind, not because one mind is superior to several, but because dividing the thing too early changes the thing. Ooloi needed a period before that could happen.

That period has had its own cost. Solitude removes obstruction, but it also removes alibis. Every accepted decision is mine. Every inconsistency in the documents is mine to catch. Every time Claude Code proposes a convenient shortcut, I have to know whether it's harmless, local, or the kind of thing that looks harmless now and grows teeth later. There's no one else to blame, which is excellent architecture and poor comfort.

The AI has made the solitude more productive, though only because the architecture constrains it. Claude works best as an implementor inside settled boundaries. Give it one subsystem, clear invariants, failing tests, and a narrow target, and it moves with astonishing speed. Ask it to hold the whole system in its head at once, and it becomes what all of us become under those conditions: less intelligent than advertised. Every subsystem sealed below the musical floor is one fewer thing it has to juggle when the visible engraving work begins.

That's another reason the long groundwork was worth doing. The cleared desk isn't a metaphor I use lightly. It's how the next phase becomes possible.

The 3 June proof mattered because it compressed much of this into one modest action. Two laptops. One Ooloi hosting, one connected. A flute name changed on the guest, visible on the host. Undo on the host, reverting the guest's edit. The revert appearing on the guest.

As cinema, it will not trouble Bergman. As architecture, it was the exact kind of evidence I had been waiting for.

That little proof did not show engraving, and it did not pretend to. It showed authority, transport, shared state, invalidation, fetch, undo routing, and cross-machine propagation acting together without ceremony. Nearly two years of decisions appeared as a small correction to the name of a flute. Software milestones are sometimes like that: not fireworks, just a door opening without sticking because someone spent a very long time caring about the hinge.

Now the work is moving towards the page.

The custom picker is already visible and operable. It's not a native file chooser with new paint. It asks the backend what exists, receives opaque tokens, and never sees paths. Local storage and remote storage go through the same contract. The boring dialog is already the front edge of the piece model.

Behind it, the piece window is now a live view of authoritative backend state, and this anniversary comes with a second small proof to show it. The video accompanying this post was recorded on two machines. On one, a wind quintet is assembled in a handful of gestures: flute, oboe, clarinet, horn, and bassoon dragged out of the Instrument Library into the Musicians panel of a shared piece window, each becoming a musician with its staves beneath it, and then dragged across into the Layouts panel to define the full score and the five individual parts. On the other machine, the same piece window answers. No delta is sent between them: a structural change names what is now stale, and the other screen refetches the canonical structure and redraws.

It's the 3 June proof one storey higher. In June a flute changed its name and the plumbing held; here the same architecture carries piece structure rather than a library entry, edited collaboratively, with the invalidate–fetch–replace model the Instrument Library established generalising to the piece itself unchanged. And it's still, deliberately, not engraving. What crosses the wire and appears on the second screen is musical structure, not a rendered stave. There's no notehead in the video. The machinery that'll carry the music is running, and running across two machines, before the music arrives.

Next come piece preferences and window persistence, the rest of the Piece Window arc. After that, MusicXML, because real scores must drive real notation work. Then Skija and the rendering pipeline. Then the noteheads: spacing, stems, flags, dots, accidentals, voices, collisions, beams, ties, slurs, hairpins, lyrics, pedalling, ottavas, tuplets, and the geometry of the page.

The evidence will change again at that point. The collaboration you can already see in the video will still be there, but it'll be moving notation rather than structure. A slur will find space. A beam will sit, straddle, or hang. A note in a chord will change geometry around it. One screen will alter shared musical notation and another will answer with the same page. The program will make the argument in engraving, not only in structure.

I'm looking forward to that more than I can sensibly say.

Two years in, the thing that surprises me isn't that there's still no music on screen. I expected that. The noteheads were never beside the point as a goal, only as evidence; a program isn't proved by what it can draw first. The surprise is how much of the project is already behind the moment when music appears. The empty stave, seen from the surface, suggests absence. The inventory tells a different story: a great deal has already been decided, tested, closed, and made boring.

Boring is underrated. Boring is what a foundation becomes when it's doing its job.
​​
So, coming out from the darkness that never really was, the next part will be visibly brighter, and with any luck it will involve fewer ... certificate files.
2 Comments

Ghosts of Competitions Past

16/9/2024

0 Comments

 
Picture
A recent question in the Clojurians Slack channel caught me off guard when I was asked to compare FrankenScore to Sibelius. This request for a direct comparison not only made me pause but also brought back memories of Igor Engraver's rivalry with Sibelius – a competition that once saw Sibelius's own CEO defect to our side. However, that was a long time ago. Now, as FrankenScore carries forward Igor's legacy, I was challenged to articulate our unique value proposition in this new era.

​Here's how I responded:


NN:
Hey, that looks promising! What are the advantages it will have compared to Sibelius?

Peter Bengtson:
Wow, that's actually a pretty multi-faceted question. While we're still in development and can't yet offer a feature-by-feature comparison with Sibelius, I can highlight some key advantages we're aiming for:
​
  1. Open-source: FrankenScore will be open-source, allowing for community-driven development and customisation. This should enable faster evolution and adaptation to user needs.
  2. Modern architecture: Built with Clojure, it leverages functional programming paradigms that offer benefits in areas like concurrency and data processing. This leads to better performance, especially for complex scores. FrankenScore is explicitly designed to support very large scores.
  3. Truly cross-platform: Frankenscore will run on Mac, Windows, and Linux.
  4. User experience focus: We're recreating the intuitive interface and multi-modal input mode that Igor Engraver was well known for (and which Sibelius partly copied – unsuccessfully – after Igor's demise). This allows a musician to input music easily and very quickly just like with pen and paper, without switching between tools. The result is an enhanced creative process that flows naturally, rather than one hindered by arbitrary technological barriers.
  5. Extensible plugin system: FrankenScore consists of a small, highly efficient core, augmented with plugins. It will support both open-source and commercial closed-source plugins, written in any JVM language. Plugins run on the same terms as the core and are an important and integral part of the architecture, not an afterthought. The API is highly abstract and takes care of all the low-level details such as transactions and thread-safety so that plugin developers can concentrate on functionality. Writing plugins for FrankenScore should be a doddle.
  6. Full SMuFL font support: Unlike Sibelius, FrankenScore makes full use of the capabilities of SMuFL music fonts.
  7. Collaborative features: We're exploring real-time collaboration possibilities to enhance how musicians work together on scores. This is possible since FrankenScore uses a server/client architecture.

​Importantly, as an open-source project, FrankenScore will be free to use. Many music departments struggle with excessive license costs.
​
For those interested in more details, ooloi.org contains a wealth of information about the project, its goals, and its technical underpinnings.
0 Comments

Why resurrect Igor Engraver now?

7/8/2024

4 Comments

 
Picture
Twenty-five years ago, I embarked on a journey to revolutionise music notation software with Igor Engraver. Today, I'm resurrecting that spirit with FrankenScore. But why now? Why breathe new life into a project that's been dormant for a quarter-century?

A Vision Deferred

Igor Engraver was always meant to be freeware, a tool for musicians and composers to express their creativity without financial barriers. Commercial considerations, however, steered us away from that vision. Now, with FrankenScore, we're returning to those roots by embracing open-source development. This aligns with my original intentions and the spirit of accessibility that drove Igor Engraver's creation.

The Tech Landscape: Then and Now

Back in '96, when Igor Engraver was born, the technological landscape was vastly different:
  • OS X hadn't been released
  • Most computers were single-core
  • Software was largely platform-specific
  • Clojure, our chosen language for FrankenScore, didn't exist

Today, we have multi-core processors, cross-platform development tools, and languages like Clojure that offer powerful abstractions and concurrent programming models. These advancements allow us to build FrankenScore as a more robust, efficient, and flexible tool than was possible with Igor Engraver.

The State of Music Notation Software

Igor Engraver was conceived because the available options at the time – Finale (as user-friendly as a cactus) and Sibelius (marginally better) – weren't up to the task. They fell short in usability, flexibility, and output quality.

I hated using Finale (and I've written an entire opera in it). Instead of enhancing your creativity – which, at the end of the day, is what a music processor should do – Finale and all other similar programs hampered your creativity.

Surprisingly, a quarter-century later, the field hasn't progressed as much as you might expect. While there have been improvements – some of them clearly inspired by Igor Engraver! – there's still a significant gap between what's available and what's possible.

Why FrankenScore, Why Now?

The time is ripe for FrankenScore, and I can't help but feel a sense of excitement and purpose. We're at a unique intersection of technological readiness and persistent unmet needs in the music notation world. The tools and platforms available to us now make it possible to build something truly revolutionary – a modern, efficient, and cross-platform solution that was merely a dream when Igor Engraver was conceived.

What strikes me is how, despite the passage of time, the music notation software landscape still leaves much to be desired, especially in terms of usability and flexibility. It's both frustrating and motivating. But here's the kicker – we now have this thriving open-source ecosystem at our fingertips. It's the perfect environment for collaborative development and continuous improvement, something I could only have wished for back in the day.

There's also a personal element to this timing. I feel a renewed focus, unburdened by the commercial constraints that ultimately derailed Igor Engraver. We can, as a community, now pour our energy into creating the best possible tool for musicians and composers, staying true to the original vision of accessibility and innovation. And you know what? Those years weren't wasted. The experiences from Igor Engraver – our successes, our setbacks, the lessons learned – they're all invaluable insights that we're bringing to FrankenScore's development. It's like we're picking up where we left off, but with 25 years of additional wisdom and technological advancements in our toolkit.

FrankenScore isn't just a revival; it's a reimagining. We're taking the core ideas that made Igor Engraver revolutionary and implementing them with modern technology and development practices. Our goal is to create a music notation tool that's not just incrementally better, but fundamentally transforms how musicians interact with notation software.

We're excited to embark on this journey, and we invite you – musicians, developers, and enthusiasts – to join us in shaping the future of music notation software. Together, let's bring Igor Engraver's vision to life in FrankenScore.

Picture

(Oh, and by the way, FrankenScore is just a pre-release working name. When we open the repo, make it open source and invite collaborators to participate, we will switch to Ooloi, just like the domain you're on right now. I'll explain the reasons in a later blog posting.)

4 Comments

    Author

    Peter Bengtson –
    Cloud architect, Clojure advocate, concert organist, opera composer. Craft over commodity. Still windsurfing through parentheses.

    Search

    Archives

    August 2026
    July 2026
    June 2026
    May 2026
    April 2026
    March 2026
    February 2026
    January 2026
    December 2025
    November 2025
    October 2025
    September 2025
    August 2025
    July 2025
    June 2025
    April 2025
    March 2025
    September 2024
    August 2024
    July 2024

    Categories

    All
    Accidentals
    Alfred Korzybski
    Architecture
    Backend
    Beaming
    Benchmarks
    Clefs
    Clojure
    CLOS
    Common Lisp
    DDD
    Death Of Igor Engraver
    Documentation
    Donald E Knuth
    Dorico
    Dynamic Programming
    Finale
    Fonts
    FrankenScore
    Franz Kafka
    Frontend
    Functional Programming
    Generative AI
    GRPC
    Igor Engraver
    Ingmar Bergman
    Instruments
    Jacques Derrida
    JVM
    License
    LilyPond
    Lisp
    Localisation
    MIDI
    MPL 2.0
    MuseScore
    MusicXML
    Ooloi
    Ortography
    Pitches
    Platforms
    Playback
    Plugins
    Python
    QuickDraw GX
    Rendering
    Rhythm
    Rich Hickey
    Road Map
    Scheme
    Semiotics
    Sibelius
    Silicon Valley
    Site
    Skia
    Sponsorship
    Transposition
    UI
    Umberto Eco
    Vertigo
    VST/AU
    Wednesday Addams

    RSS Feed

Home
​Overview
Documentation
About
Contact
Newsletter
Ooloi is an open-source desktop music notation system for musicians who need stable, precise engraving and the freedom to notate complex music without workarounds. Scores and parts are handled consistently, remain responsive at scale, and support collaborative work without semantic compromise. They are not tied to proprietary formats or licensing.
​
Ooloi is currently under development. No release date has been announced.


  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Technical Comparison
  • Documentation
  • About
  • Contact
  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Technical Comparison
  • Documentation
  • About
  • Contact