# Texture is a structured content editor for JATS, and the Dar format is the strict part

> An open source word processor for scientific publishing, built on the Dar format which is a stricter form of the JATS XML standard. It runs as a web app, as an Electron desktop application, and the interesting engineering is in how the document model and the XML round trip are kept in step.

**substance/texture** — A visual editor for research.

- Repository: https://github.com/substance/texture
- Stars: 1,012 · Forks: 86
- Language: JavaScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/substance-texture

## Dar is a restricted JATS, and the restriction is the feature

Texture is a toolset designed for the production of scientific content. It uses the Dar Format, which defines a stricter form of the JATS Archiving and Interchange Tag Set, the green v. 1.1 XML standard.

That single sentence is the design of the whole project. JATS is a large specification covering article structure, references, figures, tables, supplementary material and a long tail of publisher-specific markup, and any tool that tries to support all of it ends up being a text editor with a schema. Dar takes a subset of JATS and defines it strictly, which means the document model in the editor can be complete, and the XML it produces is predictable.

For a publisher or a scholarly editor, that predictability is worth more than generality. A stricter format means the round trip through the editor is trustworthy, because the set of things that can be represented is small enough to reason about.

The project is developed by the Substance Consortium, formed by the Public Knowledge Project, the Collaborative Knowledge Foundation, SciELO, Érudit and eLife, and the README lists the individual contributors with their roles, which include leadership, concept, dev, requirements, design and UX. Those role labels are unusual to see in a README and they tell you the project ran a proper process with a designer and a requirements person in it, not just developers.

The licence is MIT, and the README is explicit that you are legally free to use it commercially, with the expectation that if you are making profit you help fund its development and maintenance through the consortium. The recent release tags are v2.3 from 2019-04-12, v2.2 from 2019-03-28 and v2.1 from 2019-03-12, and the package version in the metadata is a preview, 3.0.0-preview-5.

## Running it is a clone, an npm install and a dev server

The install path is short and the prerequisite is stated first. You need Node 8.x installed on your system.

Then clone the repository.

```bash
$ git clone https://github.com/substance/texture.git
```

Navigate to the source directory.

```bash
$ cd texture
```

Install via npm.

```bash
$ npm install
```

And start the dev server.

```bash
$ npm start
```

Then navigate to `http://localhost:4000`, and the README gives the full URL with the query parameters for the sample archive and the storage backend, which is `?archive=kitchen-sink&storage=fs`.

Those two parameters are worth understanding because they tell you how the editor stores and loads documents. The archive selects which sample document is loaded, and the storage selects the backend, here the file system. That is the seam where the editor stops being a fixed demo and starts being a tool for your own content.

The manual step for your own material is simple. To test with your own JATS documents, just replace the contents of `data/kitchen-sink/manuscript.xml`. That is a deliberate design: the sample doubles as the entry point for real work, and you are not asked to configure a plugin or register a document type.

Saving is a keyboard shortcut, CommandOrControl+S, which is the standard expectation for a document editor and the kind of detail that separates a tool meant to be used from a demo.

The desktop application is the same code wrapped in Electron.

```bash
$ npm run app
```

And packaging it for distribution is a separate command.

```bash
$ npm run release
```

On macOS you can then run the installed application from the command line against a file.

```
open -a /Applications/Texture.app my-article.dar
```

That command takes a `.dar` file, which is the format Texture works in, and it shows that the desktop build is a document handler for its own file type rather than just a window.

## The test suite runs in Node, in the browser and in Electron

The testing setup is more thorough than most projects of this age, and the three ways of running the tests are worth describing because each one catches something the others cannot.

Running tests in NodeJS, the way it is done on TravisCI, is the base case.

```bash
npm test
```

Debugging the NodeJS tests uses the inspector.

```
node make test-nodejs && node --inspect-brk --require esm test/index.js
```

Then you open `chrome://inspect`, and it should show a Remove Target for the test script, and clicking on inspect opens a new window with Chrome Developer Tools.

Running some of the NodeJS tests uses an environment variable as a filter.

```
TEST="Model" npm test
```

The environment variable `TEST` is used as a filter to select tests that have that pattern in their name, which is the way you narrow down a failing run in a large suite.

Running tests in the browser is a different command.

```
node make test-browser -w -s
```

Then you open `localhost:4000/test`.

The browser suite matters more than it might appear. Texture is an editor, and the behaviours that break are the ones involving the DOM, focus, selection and rendering, and a Node test cannot reach any of that. Running the same test suite in a real browser is how you find out that a key handler works when focus is in a nested editor rather than in the document body.

The package scripts show the same three targets with names. `test` runs `npm run test-nodejs` and the Node script pipes the output through `tap-spec`, so the results are in a readable format. There are `test-nodejs`, `test-browser` and `test-electron` scripts, and `test-debug` which starts the inspector. The `pretest` script runs the linter first, so a lint failure stops the tests before they run.

The linter is `standard`, with the lint script covering the builds, src and test directories, and the `prepack` script runs an install and the publish step of the custom `make.js` build.

## A custom build script over Rollup, with the document model in TypeScript

The package manifest explains the architecture, and it is a JavaScript project with a build layer that predates the modern bundler defaults.

The build tool is `make.js`, invoked through the npm scripts. `start` runs `node --require esm make dev -s -w -d data`, which starts the development build in watch mode against the data directory, and `app` runs `node make run-app -w` for the Electron application. The `esm` package is what allows the ES module source to be loaded directly by Node, without a compile step, which is why the dev server starts fast.

The bundling is Rollup, at version 1.11.3, with the commonjs and node-resolve plugins, and the build targets are declared in the manifest with `main` pointing at a CommonJS bundle and `browser` at an ES module bundle, plus a `jsnext:main` entry for the source. The `substance-bundler` package at 0.26.4 is what actually performs the packaging, and `substance` itself at 1.0.2 is both a dependency and a peer dependency, which is the correct arrangement for a document model that the host application also needs.

The runtime dependencies are small and each has a purpose. `debug` for logging, `fs-extra` for file operations, `katex` at 0.10.0 for rendering mathematics inside the editor, and `yauzl` and `yazl` for reading and writing zip archives, which is how a document with its assets gets packaged.

The dev dependencies show the scientific publishing side. `texture-plugin-jats` and `texture-xml-utils` are the two packages that carry the JATS and Dar handling, and they are versioned separately from the editor itself, which is the right split because a schema change and an editor change are different kinds of work.

There is also `parse-formdata` for handling form submissions, `nyc` and `istanbul-lib-instrument` for coverage, `electron` and `electron-builder` for the desktop application, and `inter-ui` and `font-awesome` for the interface fonts.

## What the state of the project means for a dependency decision

The maintenance picture needs to be read carefully, because it is a mixture of two signals.

The positive signal is that the repository is not archived and the last push was on 2026-04-07, so there has been recent work. The version in the package manifest is a preview, 3.0.0-preview-5, which tells you the 3.x line is in progress rather than abandoned.

The negative signal is the release history. The tagged releases are v2.1, v2.2 and v2.3, all from March and April 2019, and the gap since then is more than seven years. The last pushed work and the last release are a long way apart.

That combination is a common pattern for a project whose home is a consortium rather than a company. The code does not need to release often because the consuming organisations run it themselves, and the development happens in the open across several organisations rather than in a single release train.

For a decision, the questions are concrete. If you are a publisher with a team that can maintain a fork, the consortium structure is a feature, because the governance is spread across five organisations and the licence lets you take the code commercially. If you are a small team that needs vendor support and a predictable release cadence, this is not that, and the 2019 tags are the evidence.

The other thing to check is the foundation it stands on. The `substance` package at 1.0.2 is the document model underneath, and it is a peer dependency, so your application needs a compatible version of it too. A dependency on a document model is a much deeper commitment than a dependency on a text editor component, because the document model determines the shape of everything above it.

The changelog at the root and the `docs/` directory are where you would look for the state of the 3.x work, and the `builds/` directory holds the build configurations.

## Conclusion

Adopt Texture if you are editing JATS scientific articles and want a structured editor rather than a word processor over XML, and you are willing to work within the Dar subset. Do not adopt it for general long form editing or for content outside the publishing workflow it was designed for, because the value is precisely in the constraints it imposes. Verify first that the documents you need fall inside the Dar format rather than full JATS, that your environment still runs the Node version the project expects, and that the upstream consortium's maintenance status suits a dependency you are about to rely on.

## FAQ

### What is Texture and what format does it use?

Texture is a toolset designed for the production of scientific content. It uses the Dar Format, which defines a stricter form of the JATS Archiving and Interchange Tag Set XML standard, so the document model in the editor can be complete and the XML output predictable.

### How do I run Texture locally?

You need Node 8.x installed. Clone the repository, cd into it, run npm install, then npm start, and open http://localhost:4000 with the query parameters for the sample archive and the file system storage backend.

### How do I test my own document in Texture?

Replace the contents of data/kitchen-sink/manuscript.xml with your own JATS document, then start the dev server and select that archive. Saving is done with CommandOrControl+S.

### How do I run the Texture test suite?

In Node with npm test, in the browser with node make test-browser -w -s and then localhost:4000/test, and the TEST environment variable filters Node tests by name pattern, for example TEST="Model" npm test.

### What licence is Texture released under and who develops it?

It is open source under the MIT licence and you are legally free to use it commercially. It is developed by the Substance Consortium, formed by the Public Knowledge Project, the Collaborative Knowledge Foundation, SciELO, Erudit and eLife.

## Sources

- [Issues](https://github.com/substance/texture/issues)
- [License: MIT](https://github.com/substance/texture/blob/master/LICENSE)
- [README](https://github.com/substance/texture/blob/master/README.md)
- [Releases](https://github.com/substance/texture/releases)
- [substance/texture on GitHub](https://github.com/substance/texture)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/substance-texture
