valign lines up Org and Markdown tables on a proportional font
Pixel-perfect visual alignment for Org and Markdown tables.
At a glance
- What is it?
- valign is an Emacs Lisp package that visually aligns Org Mode, Markdown and table.el tables in a GUI Emacs, handling variable-pitch fonts, CJK characters and images, while leaving the text alignment the modes generate untouched. It is a single valign.el file, its newest tagged release is v3.1.1 from 2021, and the last push was on 2026-04-17.
- Who is it for?
- valign is a good fit for someone who reads Org or Markdown tables in a GUI Emacs with a proportional font and has stopped noticing that the columns do not line up, and who wants a visual fix that leaves the underlying text alignment alone so exports stay valid.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Emacs Lisp, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the package actually changes
valign provides visual alignment for Org Mode, Markdown and table.el tables on GUI Emacs, and it can properly align tables containing a variable-pitch font, CJK characters and images. The mechanism is composition rather than rewriting. The text-based alignment that Org mode or Markdown mode generates is left untouched, so the buffer content is exactly what those modes produced, and the visual alignment is layered on top of it in the display. That is the whole design, and it is why the package does not fight with your exporter: an Org table exported to HTML still has the original text alignment, which is the alignment a text renderer needs, while your screen shows columns that line up under a proportional font. The alternative, converting the buffer to a monospaced font for the sake of the table, changes how everything else in the document looks and how it exports.
Turning it on
Usage is a single hook. You load the package and add valign-mode to org-mode-hook or markdown-mode-hook:
(add-hook 'org-mode-hook #'valign-mode)The package can be obtained from GNU ELPA through the standard package-install command:
M-x package-install RET valign RETThe README is a plain Org file, README.org, with a Chinese translation in README-CN.org, and the package itself is one file, valign.el, at the top of the repository alongside a Makefile and a test.org file that the Makefile targets use. The Makefile has four targets that each run a clean Emacs with the package loaded and the test file opened: test, which enables valign-mode and variable-pitch-mode, bar, which additionally sets valign-fancy-bar to t, indent, which also sets org-startup-indented and jumps to the end of the buffer, and mono, which enables valign-mode without variable-pitch-mode, which is the case where there is nothing to align visually.
The known problems, stated plainly
The README lists two known problems and they are the ones that decide whether the package is useful for you. The first is that hidden links in Markdown still occupy the full length of the link, because valign uses character composition, which the package does not support. In other words, a Markdown link whose display text is shorter than its target will still reserve the target's width in the visual layout, so a table containing hidden links will look misaligned even though the mechanism is working as designed. The second is performance: rendering large tables of 100 lines or more is laggy. Neither is a bug report, both are limits of the approach, and both are things you discover only by having a table with hidden links or a hundred rows.
table.el tables have a layout contract
If you use table.el tables, the README sets out a requirement that is easy to miss. For table.el tables to work with valign, each cell has to have at least one space on the right and no space on the left. The suggested fix is ftable.el, by the same author, which can auto-layout the table for you. This is a consequence of how valign composes cells, and it means an existing table.el document may need reformatting before the package will line it up, which is a real cost if you have a lot of them. The other customization for table.el is valign-box-charset-alist, used to define the table.el tables, for example Unicode or ASCII tables, which tells you the package expects to know which character set the box drawing is using before it can compose the cells correctly.
The customization surface, and what each option does
There are four options that matter beyond the mode itself. valign-fancy-bar set to non-nil adds a bar, and the README notes that this only affects Org Mode and Markdown tables. valign-not-align-after-list is a list of commands after which valign should not re-align the table, which addresses the default behaviour that valign does not re-align after normal edit commands such as self-insert-command and backward-kill-word. valign-max-table-size is the character threshold above which valign declines to align, set at 4000 by default, and the package puts the valign-table-fallback face on those large tables so they still look deliberate. valign-signal-parse-error set to non-nil informs you about parse errors, and valign-lighter makes the mode line lighter. The two that decide the day-to-day feel are the command list and the table size limit, because they are the two places where the package's efficiency shows.
The advice problem, which is a real trap
The README has a section titled if function advice makes you itch, and it explains a genuine footgun. valign-mode adds advice and does not remove it even if you close valign-mode, because function advice is global while valign-mode is local. The consequence is that the advice stays in place after you turn the mode off, and the recommended remedy is valign-remove-advice, with the warning that if you run it while some buffer still has valign-mode on, those buffers break. So the sequence matters: remove the advice only once no buffer is relying on it. This is a small thing, but it is the kind of detail that separates a package written by someone who has debugged in production from one written for a demo, and it is the reason the README mentions it at all.
Where valign is the wrong tool
Three cases. The first is a terminal Emacs, because the package is for GUI Emacs and the whole technique is visual composition of a display that a terminal cannot represent. The second is a document with large tables, since the README says rendering 100 lines or more is laggy and tables over 4000 characters are skipped entirely and given a fallback face instead of an alignment. The third is a workflow that depends on the text alignment being the visible one, for instance a table you read aloud from a shared terminal session or a document where the alignment is the point. Against converting the buffer to a monospace font, the difference in approach is that valign leaves the text alone and fixes the display, which keeps the export correct and the rest of the document proportional, at the cost of a composition step per cell and the known problems around hidden links and large tables.
Editorial conclusion
valign is a good fit for someone who reads Org or Markdown tables in a GUI Emacs with a proportional font and has stopped noticing that the columns do not line up, and who wants a visual fix that leaves the underlying text alignment alone so exports stay valid. It is a poor fit for a terminal Emacs, since the package is explicitly for GUI Emacs, and it is a poor fit if your tables are large, because the README says rendering tables of 100 lines or more is laggy and tables beyond 4000 characters are not aligned at all. Check three things before you switch it on: that you are in a GUI Emacs with variable-pitch support, since the whole point is proportional rendering, that your table.el tables have a space on the right of each cell and none on the left, since that is the layout valign expects and ftable.el is suggested to produce it, and that you are willing to keep the mode local, because valign-mode adds global advice that it does not remove when you turn the mode off, so a buffer left with valign-mode on breaks.
Frequently asked questions
What does valign do in Emacs?
It provides visual alignment for Org Mode, Markdown and table.el tables on GUI Emacs, including tables with a variable-pitch font, CJK characters and images, while leaving the text-based alignment that Org mode or Markdown mode generates untouched.
How do I enable valign?
Load the package and add valign-mode to org-mode-hook or markdown-mode-hook, for example (add-hook 'org-mode-hook #'valign-mode). You can install it from GNU ELPA with M-x package-install RET valign RET.
What are the known problems with valign?
Hidden links in Markdown still occupy the full length of the link, because the package uses character composition which it does not support, and rendering large tables of 100 lines or more is laggy. Tables larger than 4000 characters are not aligned at all and get the valign-table-fallback face instead.
What do table.el users need to do for valign to work?
Each cell has to have at least one space on the right and no space on the left. The README suggests ftable.el, by the same author, to auto-layout the table for you, and valign-box-charset-alist is the option used to define the table.el tables, for example Unicode or ASCII ones.
What is the valign function advice issue?
valign-mode adds advice and does not remove it when you close the mode, because function advice is global while the mode is local. The remedy is valign-remove-advice, but the README warns that running it while any buffer still has valign-mode on breaks those buffers.
Official sources
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.
[](https://hysenlabs.com/projects/casouri-valign)Was this useful?