Library / SDK
spatialillusions/milsymbol avatar
spatialillusions/milsymbol

milsymbol: military unit symbols drawn as code, with version 3.0 trading fidelity for consistency

Military Symbols in JavaScript

815 stars176 forksJavaScriptMIT

At a glance

What is it?
milsymbol is a pure JavaScript library that draws military unit symbols for MIL-STD-2525 and STANAG APP-6, with no images and no fonts. The significant decision is in version 3.0, where rendering follows the newest appendices even when older documents show a different shape.
Who is it for?
milsymbol fits a JavaScript application that has to place standard unit symbols on a map or in a diagram and needs to switch between 2525 and APP-6 without a redesign. It does not fit a project that must reproduce an older appendix symbol exactly as printed, and it does not fit a workflow that needs the closed source extensions the author keeps outside the repository.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The symbols are geometry, not images

milsymbol is a small library in pure JavaScript that creates military unit symbols according to MIL-STD-2525 and STANAG APP-6. The design decision that defines the project is stated plainly in the technology section: the symbols are created using building blocks defined in the code, and no images or fonts are used.

That single constraint is what makes the library useful. Because the frames, fills and strokes are drawn rather than blitted, almost every aspect of a symbol can be modified, including fill, frame, color, size and stroke width, and the symbology can be switched between APP-6 and 2525. A symbol library built on images can only be scaled, and a symbol library built on fonts depends on the fonts being present. This one depends on neither.

The other technology claims are about weight and speed. The library has no external dependencies, so a single JavaScript file is all that is required, and the README states that it can create 1000 symbols in less than 20 milliseconds with SVG output. That is the project's own figure, and it is the kind of claim worth testing in your own page, since a map with a thousand markers is an ordinary case rather than an extreme one.

The library is created and maintained by Måns Beckman, and the licence is MIT with the details in the LICENSE file.

A SIDC code goes in, draw instructions come out

The API is small enough to describe in a paragraph. You create a symbol with the symbol method, ms.Symbol(SIDC,{options}), and for an infantry platoon the SIDC string looks like this:

javascript
var sym = new ms.Symbol("130310001412110000000000000000");
sym.setOptions({size:35});
var canvasElement = sym.asCanvas();

The symbol object that comes back contains information about the size and the draw instructions, which is worth pausing on. It is not an opaque handle to a renderer, it is the drawing itself, and that is what makes the output flexible.

For output there are two paths, and the README is direct about the choice. asCanvas() returns a canvas element containing the symbol and asSVG() returns an XML representation of the SVG, and you use whichever method gives you the output you want. If you do not want to make it step by step, the calls chain, so a symbol can be created and rendered in one expression.

Options can be supplied at construction or changed later with setOptions(options), and they control the size of the symbol, whether it is filled or unfilled, and add text information among much else. The symbol object also carries the offset needed for correct placement, retrievable with getAnchor(), which returns an object with the x and y offset, along with information about the size of the created symbol and the detailed colors used.

The last line of the getting started section states the project's ethos: everything used inside milsymbol should be accessible outside milsymbol, so that it is easy to extend the library with custom functionality.

Version 3.0 made symbols uniform across appendices, on purpose

Since version 3.0, symbology is rendered as closely as possible to MIL-STD-2525E, STANAG APP-6 E and FM 1-02.2, even if the symbol might look slightly different in older standard documents. The stated reason is to make symbology uniform between systems that use different versions of the SIDC codes, and it adds that in some cases where symbols are inconsistent between different appendices in the standard documents, they have been made consistent for easier interpretation.

This is a trade-off, and it is the one a reader has to accept or reject explicitly. The older appendices really did differ in places, and a map that mixes symbols from two systems can end up with the same unit drawn in two different ways. Normalising to the newest appendix removes that ambiguity. It also means that if your reference is a printed figure from an older appendix, the library will not reproduce it exactly, which is why the README shows the comparison with a reference figure from MIL-STD-2525C and notes the difference.

The standards covered are the NATO and US set: MIL-STD-2525C, MIL-STD-2525D, MIL-STD-2525E, FM 1-02.2, and STANAG APP-6 B, D and E. The option surface adds filled and unfilled symbols, framed and unframed symbols, text fields, movement indicators, and outlines of symbols.

For a team whose operational display must match a document set from a given year, this normalisation is a real cost. For a team whose data comes from several systems and needs one visual language, it is the feature.

Integrations, examples and how the package is shipped

The library is written to be dropped into whatever stack you already have. The README lists Angular, Cesium, D3, Leaflet, Node.js and Open Layers 3 among the common JavaScript libraries it integrates with, and it also works in the ScriptEngine in Java and the QtJSEngine in C++. Examples of some of those integrations are included with milsymbol.

The examples directory in the repository shows how varied that list is in practice: an arcgis3d example, a d3-list example, an es6-import example, leaflet-divicons and leaflet-imageicons examples, an openlayers example, an outline example, speed-canvas and speed-svg benchmarks, a stack example, a style example, and a situation.json data file. Two of those are performance comparisons of the two output paths, which is a sensible thing for the project to publish given the speed claim.

The packaging is modern and worth noting if you consume it from a bundler. The package is ESM, with an exports map that sends require() to the bundled CommonJS file in dist/, import to the root index.js, and types to index.d.ts, and the main, module and browser fields point at the same alternatives. The build is a rollup bundle followed by uglifyjs minification, and a postbuild step writes a dist/package.json marking that directory as CommonJS so the two module systems can coexist in one package. The test command runs tead with coverage, and linting is eslint over src and test.

The documentation approach is unusual and effective. The unit test documents in the docs folder list all tables and figures from the different standards, and the documents render every image using milsymbol itself, so the reference pages and the implementation cannot drift apart.

The closed source extensions live outside the repository

The extending section points at a tool, the unit generator, that uses a modified version of milsymbol with closed-source extensions named stack-extension, reinforced/reduced-extension and country flag-extension, and it asks readers to contact the author if they want to use them in their own project.

That is the boundary of what the open source library covers, and it is worth knowing before you plan a feature that needs stacks of units, reinforced or reduced unit indicators, or country flags. The framework is available in the repository, those three extensions are not, and the request to the author is the stated route to using them.

The maintenance picture is straightforward. The tagged releases are v3.0.4 on 2026-03-10, v3.0.3 on 2025-07-29 and v3.0.2 on 2025-04-11, the last push to the repository was on 2026-10-19 with the repository not archived, and the package manifest version is 3.0.6. The CHANGELOG.md and CONTRIBUTING.md files are in the repository root.

For an open source library, the licensing is the simplest case: MIT, with the terms in the LICENSE file. The README also points to a buymeacoffee page for supporting the work, which is the usual arrangement for a project maintained by one person.

Where milsymbol is the wrong tool

The first wrong fit is a requirement to reproduce a specific historical figure exactly. Version 3.0 deliberately normalises differences between appendices, so a symbol drawn from the library will not always match the printed figure in an older standard document. If your deliverable is a document that has to look like the appendix, you need the older behaviour, which means an older release.

The second is a workflow that needs stacks, reinforced and reduced indicators, or country flags. Those are the closed source extensions, and the library on its own does not include them.

The third is a stack that is not JavaScript. The library is pure JavaScript with SVG and Canvas output, and while the README mentions running it in the ScriptEngine in Java and the QtJSEngine in C++, those are host environments for a JavaScript engine rather than native bindings, and the project is not a C library with a C API. For a native application, the realistic path is to generate the SVG elsewhere and embed it, which moves the rendering out of your application and into a build step.

The fourth is a heavy map with a large number of symbols and a hard frame budget. The claim of 1000 symbols in under 20 milliseconds is for SVG output and comes from the project, and the two speed examples in the repository compare the Canvas and SVG paths, which is the right thing to compare. Before you commit to drawing every marker as a vector path, measure it in your own renderer, because the number of symbols is only one of the two variables, the other being how your map layer composites them.

The fifth is a team that needs a maintained, standardised library with a support commitment. This is one author's work, released under a permissive licence with a buymeacoffee link, and the readme asks for nothing more than that.

Editorial conclusion

milsymbol fits a JavaScript application that has to place standard unit symbols on a map or in a diagram and needs to switch between 2525 and APP-6 without a redesign. It does not fit a project that must reproduce an older appendix symbol exactly as printed, and it does not fit a workflow that needs the closed source extensions the author keeps outside the repository. Before adopting it, render a symbol with your own SIDC codes and compare it against the reference figures in the docs folder, because version 3.0 deliberately normalises differences.

Frequently asked questions

What is milsymbol?

It is a small library in pure JavaScript that creates military unit symbols according to MIL-STD-2525 and STANAG APP-6. The symbols are built from drawing primitives in code, with no images and no fonts, and the library has no external dependencies.

How do I install milsymbol and draw my first symbol?

You can download the library from GitHub or install it from npm with npm install milsymbol, then create a symbol with ms.Symbol(SIDC,{options}) and render it with asCanvas() or asSVG(). A symbol object also carries placement information that getAnchor() returns as x and y offsets.

Which standards does milsymbol support?

The NATO and US set is covered: MIL-STD-2525C, MIL-STD-2525D, MIL-STD-2525E, FM 1-02.2, and STANAG APP-6 B, D and E. Options cover filled and unfilled symbols, framed and unframed symbols, text fields, movement indicators and symbol outlines.

What changed in milsymbol version 3.0?

Symbology is now rendered as closely as possible to MIL-STD-2525E, STANAG APP-6 E and FM 1-02.2, even where the symbol would look slightly different in older standard documents. The reason given is to make symbology uniform between systems that use different SIDC versions.

Can I use milsymbol with a country flag or a stack of units?

Not from the open source library alone. The unit generator tool uses a modified version of milsymbol with closed-source stack, reinforced and reduced, and country flag extensions, and the readme says to contact the author to use them in a project.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. spatialillusions/milsymbol on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/spatialillusions-milsymbol.svg)](https://hysenlabs.com/projects/spatialillusions-milsymbol)

Was this useful?