# detexify: a Middleman front end for a LaTeX symbol classifier

> This repository is the web front end of Detexify, a LaTeX symbol classifier that runs as a service, and the README is a working set of notes rather than a polished document. That is its charm and its warning: a Ruby 2.1 era Middleman site whose real work happens in a separate Haskell backend.

**kirel/detexify** — Latex Symbol Classifier Web Frontend

- Repository: https://github.com/kirel/detexify
- Website: detexify.kirelabs.org
- Stars: 851 · Forks: 52
- Language: Sass
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/kirel-detexify

## Two projects, one service

The repository is explicit about what it is and is not. It is the front end of a LaTeX symbol classifier that runs as a web service, and the classifier backend lives in a separate project, detexify-hs-backend, at another address in the same organisation.

That split shapes everything in this repository. There is no model, no inference code and no data here. What there is, is the site that a browser talks to, the configuration that tells it where the backend is, and the machine-readable list of the symbols the service knows about.

The site itself is built with Middleman, a static site generator, and the front end styling is Sass, which is why the primary language recorded for the repository is Sass. The repository listing shows a conventional Middleman project: a config.rb, a source/ directory with the templates and assets, a public/ directory for the built output, a lib/ directory for the Ruby library code, a Rakefile for the build tasks, a Procfile and a config.ru for the Rack server that serves the built site, and a spec/ directory for the tests.

The licence is MIT, with the copyright held by Daniel Kirsch and dated 2009 in the notice, and the last push was on 2026-05-16. The repository publishes no GitHub releases, so the deployment history is in the commit log rather than in tags.

The service itself is at detexify.kirelabs.org, and the site in the repository is the thing that makes that address work.

## Setup is three commands, and the environment file does the work

The Setup section of the README is a list of requirements and two commands.

You need Ruby 2.1.2 and Bundler, then the bundle command installs the gems, and then the development server is started through dotenv and Middleman:

```bash
bundle
```

```bash
bundle exec dotenv middleman
```

The production path is a static build followed by a Rack server:

```bash
bundle exec middleman build
bundle exec dotenv rackup
```

After that you open the local address, and the README says the port is 9292. The important detail is what the dotenv prefix is doing. The application is configured through environment variables, and the dotenv tool loads them from the environment file in the repository root before the process starts, so the same commands work locally and in production without a separate configuration system.

The README also notes that this runs the front end locally while using the production backend, and it points at the backend repository for the instructions on running that side locally. So a local setup is front end against a live service unless you also stand up the backend, which is the arrangement the README assumes and the one most contributors will have.

For the front end, that separation is fine. The site renders, the page loads, and the calls go to the hosted classifier.

## Symbols live in a YAML file, and a sprite is generated from them

The part of the README that is genuinely instructional is the section on adding symbols, and it describes a four-step loop that is worth reading even if you never add one.

The symbols are configured in a YAML file under the lib/latex directory, and the README warns that you need LaTeX installed to work on it, which makes sense when the symbol set is a set of LaTeX commands and the rendering has to be done to check them.

The workflow for a contributor is short. Add the symbol, run the tests, and open a pull request. The test command is the guard:

```bash
rspec spec
```

The README describes that command as checking whether all symbols compile, which is a stronger check than it sounds, since a broken symbol would fail to render and the suite would catch it before a human did.

For the maintainer there are two more steps. The sprite, which is the image set the front end draws on, is regenerated as a build artifact:

```bash
bundle exec rake symbols:sprite
```

And the deployment is a git push to the Heroku remote, which is a small piece of evidence about the era the project comes from, and about how the service is hosted. There is even a note in the Tasks section that is a reminder to the author to source their AWS credentials, because the sprite generation appears to need something from Amazon.

So the pipeline is: edit a YAML file, prove the symbols compile, generate an image set, push. The build is reproducible in the sense that every artifact comes from a file in the repository.

## The classifier is populated by a separate training step

The backend is not a black box that the front end downloads. The README has a section for populating it, and the command is a Rake task run through dotenv:

```bash
bundle exec dotenv rake populate
```

The README explains what that task does in one line, that it uses a variable named TRAINCOUCH to populate a classifier named CLASSIFIER, and points at the environment file for the defaults. The naming explains the design, a training couch is the CouchDB-style document store the examples come from, and the classifier is the thing that gets built from those documents.

So the pipeline across the two repositories is: source data lives in a document store, a Rake task reads it and builds a classifier, and the front end talks to the resulting service. The environment file holds the credentials and the default locations for all of that.

That arrangement is the main thing to understand before you try to run Detexify yourself. The front end repository can be built and served on its own, and it will look complete, and it will not classify anything without a populated backend. If you want the whole service locally, you need the backend repository, a training data source and a populated classifier, and the front end's environment file is where you point it at what you built.

The sample-tool/ directory in the repository listing is a small extra artefact of the same kind, a tool for the site to use, and the fact that it sits in the front end repository rather than in a shared package is a reminder that this codebase grew as a single deployable unit rather than as a set of shared libraries.

## The repository shows exactly how old it is

The file listing is a good dating exercise, and it explains the constraints on any contribution.

Ruby 2.1.2 is the stated requirement, and there is a .ruby-version file to pin it. The front end dependencies are managed with bower, with a bower.json at the root and a bower_components/ directory vendored into the tree, which is a workflow from before npm became the default. There is an .autotest file, the older continuous testing tool, alongside a spec/ directory run with rspec. The .slugignore file is for the Slug static hosting service, and a .env file with a .env.example pattern sits at the root, alongside a Procfile and a config.ru for the Rack deployment.

None of that is a criticism of the author, and most of it is simply what a project from that period looks like when it is still in use. The practical consequence is that a contributor today needs an old Ruby, a working bower and a LaTeX installation, and that the deployment target is a Heroku git push rather than a container image or a modern static host.

There is also a BENCH.txt file at the root, which is a benchmark record kept as a plain file rather than in a results database, and it is one more sign of a project whose artefacts are committed alongside its code.

The last push was on 2026-05-16, so the work continues, and the fact that the licence notice still carries 2009 tells you the project has outlived several of its tools without being rewritten around them.

## Conclusion

Adopt this repository if you want to run or extend the Detexify web service, and you are happy to own a Ruby 2.1 era Middleman toolchain alongside a separate backend service. Do not adopt it as a modern static site foundation, because the build pins an old Ruby, vendors front end dependencies through bower and deploys to Heroku with a git push. Before you start, read the environment file, because the backend configuration and the training data are set there, and remember that the classifier itself lives in a different repository, so a working front end on its own will not classify anything.

## FAQ

### What is the detexify repository?

It is the web front end of Detexify, a LaTeX symbol classifier that runs as a web service, with the classifier backend kept in a separate project, detexify-hs-backend. The front end is a Middleman site with Sass styling, licensed under MIT, and the service is at detexify.kirelabs.org.

### How do I set up the detexify front end locally?

Install Ruby 2.1.2 and Bundler, run the bundle command, then start the development server with bundle exec dotenv middleman. For the production path you run bundle exec middleman build and then bundle exec dotenv rackup, and open the local address on port 9292. Configuration comes from environment variables loaded from the environment file.

### How are LaTeX symbols added to detexify?

Symbols are configured in a YAML file under the lib/latex directory, and you need LaTeX installed. The workflow is to add the symbol, run the test suite with rspec spec, which checks that all symbols compile, and open a pull request. The maintainer then regenerates the sprite with bundle exec rake symbols:sprite and deploys.

### How is the detexify classifier populated?

With a Rake task run through dotenv, bundle exec dotenv rake populate, which uses the TRAINCOUCH variable to populate the classifier named CLASSIFIER, with defaults in the environment file. The training source is a document store and the backend repository holds the service that serves the resulting classifier.

### Does the detexify front end work on its own?

It builds and serves on its own, and by default it talks to the production backend, so the site renders but the classification calls go to the hosted service. To run everything locally you also need the backend repository, a training data source and a populated classifier, and you point the front end's environment variables at what you built.

## Sources

- [Issues](https://github.com/kirel/detexify/issues)
- [kirel/detexify on GitHub](https://github.com/kirel/detexify)
- [License: MIT](https://github.com/kirel/detexify/blob/master/LICENSE)
- [README](https://github.com/kirel/detexify/blob/master/README.md)

---

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