Search
All Categories
    Menu Close
    Back to all

    Bricks, calculators, and a Bible translation

    Anyone who has built a website for a builders' merchant knows the trick: put a decent brick calculator on it. Not because it sells bricks, but because it solves a real problem at the exact moment somebody has that problem.

    Small tools like that bring people back. They are the reason a visitor treats a site as somewhere to go rather than somewhere to land. Added value is what builds a community around a platform.

    We recently applied the same logic to a project that looks nothing like a builders' merchant.

    12
    keys

    Every one of them a single tap away, mid-song

    0
    rows

    Song records stored on our server

    Why a Bible study portal needed a music app

    The client behind our Croatian Bible study portal, biblija.hr, came to us with an unusual request. Alongside the study portal itself, they wanted an integrated application for musicians.

    The reasoning was sound. A community that reads and studies Scripture very often plays it as well. Worship teams and church choirs need somewhere reliable to prepare music, in the same way they need somewhere to prepare text. The two audiences are largely the same people.

    So we built Akordar: a chord sheet reader that lives inside the portal, available to approved users, and designed for the moment you are standing up with an instrument in your hands.

    The first decision: the server stores nothing

    Not "stores little". Not "stores it encrypted". There is no table, no migration, no repository, and no POST endpoint that accepts song text.

    The boundary we drew is between the server and the user's own device, rather than between memory and disk. Content a user types stays on their machine. Preferences, view state and — if they explicitly opt in — their setlist persist locally in the browser. Nothing crosses the wire.

    This started as a content decision and turned out to be an architectural gift for our nopCommerce environment. The plugin is completely stateless: no schema to version, no backups of other people's material, no database growth, nothing to clean up on uninstall. Import reads a file with FileReader, export writes one with Blob, and neither ever touches the network.

    One trap worth naming, because it is easy to walk into while believing you are doing the right thing: cookies are not client-side storage. A cookie is transmitted with every single request, which means the content ends up on the server anyway and, sooner or later, in the access logs. If the rule is "nothing reaches the server", the only honest mechanisms are localStorage and IndexedDB.

    Why most chord sheets cannot be transposed

    Almost every chord sheet in circulation puts the chords on a line above the lyrics, aligned with spaces in a monospace font. It reads perfectly well and it is completely unusable for anything else.

    The moment you transpose it, the alignment collapses. A is one character; A# and Db are two. Every chord on the line shifts relative to the syllable it belongs to, and the sheet becomes subtly wrong in a way that is hard to notice and impossible to play from.

    The fix is to stop treating the chord as a drawing and start treating it as data. Akordar stores chords inline, immediately before the syllable on which they change:

    • the chord is attached to a position in the text, not to a column on the page
    • the sheet reflows on a phone without breaking
    • chords can be hidden, recoloured, resized or transposed without touching the lyrics
    • the same file prints in one or two columns, and reads correctly in both

    This is the transferable part: whenever visual alignment is carrying meaning, that meaning is trapped. Move it into the data model and every downstream feature becomes cheap.

    Transposition is not arithmetic

    Adding two semitones to a chord is the easy half. Spelling the result correctly is where naive implementations give themselves away.

    A chord is decomposed into root, accidental, quality and bass — Bm7/F# is four separate facts. The root becomes a pitch class from 0 to 11, the interval is added, and then the result has to be written back out in the spelling that belongs to the target key. In E flat you write Ab; in E you write G#. Same pitch, different name, and a musician reading the wrong one has to stop and think.

    Get this wrong and you produce E# and Cb, which are technically defensible and practically insulting.

    There is a second trap specific to our market. In Croatian and German notation B means B flat and H means B natural, while international notation uses B for B natural and has no H at all. Assume either one and you will silently alter chords on import. It has to be a switch the user controls, not a default the developer picked.

    And because guitarists exist, the tool also computes the obvious shortcut: rather than learning new shapes in E flat, put a capo on the first fret and play in D. One line of modular arithmetic, disproportionately appreciated.

    What playing live actually demands

    Designing for a stage is not designing for a desk. The device is a phone or tablet propped on a music stand, the lighting is poor, and the user has at most one free hand for roughly four seconds at a time.

    The screen must not sleep. A wake lock while the page is open. Obvious in hindsight, infuriating in its absence.

    The interface must disappear. At rest the page shows the song and nothing else. Every control lives behind a single button in the corner. Toolbars are for editing, not for performing.

    Autoscroll at the song's own tempo, so the sheet moves by itself and both hands stay on the instrument.

    The setlist is ordered by hand, dragged into performance order, and "next song" follows that order rather than the alphabet. Worth noting for anyone building similar: HTML5 drag-and-drop does not work on touch at all. It works beautifully on the developer's desktop and not at all on the device the tool was built for.

    Three reading themes — paper, sepia and night — because a white screen at full brightness in a dark room is its own kind of hostile.

    Full screen is offered, with a caveat we had to design around: iOS Safari does not support the Fullscreen API on ordinary elements, so there is a fallback mode that strips the site chrome and achieves the same result without it.

    An unplanned side effect

    Because the format is plain text with a simple, documented grammar, it turns out to sit very comfortably alongside language models.

    A musician can take a bare three-chord sheet, ask an assistant to reharmonise it with passing chords and richer voicings, and paste the result straight back in. Akordar parses it and transposes it on the fly like anything else. We did not design for this. It fell out of choosing a text format over a proprietary one, which is an argument for text formats generally.

    Why this was worth building at all

    We looked at what already existed before writing anything. The pattern was consistent: the capable applications are commercial, and they are either aggressively ad-supported or subscription-based. The free alternatives are missing precisely the features that matter once you are actually playing — reliable transposition, autoscroll, a screen that stays on, a usable phone layout.

    What we offered instead is a clean, mobile-first tool that runs in the browser, costs nothing, shows no advertising, and keeps its users' material on their own devices.

    None of the individual pieces are hard. The reason it did not already exist in this form is that it only makes sense as an addition to a platform whose community happens to need it.

    What transfers to other projects

    The subject matter is niche. The engineering decisions behind it are not.

    Utility builds community

    A small tool that solves one real problem does more for return visits than a redesign. Ask what your audience does when they are not on your site.

    Storing nothing is a feature

    No schema, no backups of other people's content, nothing to clean up on uninstall. Statelessness is cheaper to build and cheaper to keep.

    Cookies reach the server

    If the rule is that data stays on the device, a cookie breaks it silently. Only local browser storage actually keeps the promise.

    Layout is not data

    When meaning is carried by visual alignment, it is trapped there. Move it into the model and every feature downstream gets cheap.

    Domain rules beat arithmetic

    Correct output often needs domain knowledge, not just a correct calculation. Ask a practitioner before assuming the maths is the whole job.

    Test on the real device

    Drag-and-drop that works on a desktop can be entirely absent on touch. Build for a stand in a dark room, not for the machine you develop on.

    The pleasant surprise in this project was how much of it was ordinary engineering wearing unfamiliar clothes. Parsing, state, responsive layout, an ambiguous character encoding standard — all of it recognisable, just pointed at chords instead of catalogue records.

    Sometimes the best software additions come from understanding what your community already does when it is not looking at your website.

    Is there a small tool your audience keeps improvising around?
    Custom nopCommerce plugins, integrated utilities, content platforms at scale — if your users are solving a recurring problem with spreadsheets and paper folders, that is usually a sign. You can see the wider platform this was built for at our Croatian Bible study portal, biblija.hr.
    contact us
    Comments
    Write a comment Close