Our computers can display an astonishing range of symbols. Unicode alone defines more than 150,000 characters, covering everything from mathematical operators and phonetic alphabets to emoji and obscure historical scripts. Our keyboards, on the other hand, remain stubbornly limited to a few dozen keys.
On Windows, the traditional workaround involves memorizing numeric codes or digging through character maps. Linux, being Linux, offers something far more flexible: XCompose. It’s one of those powerful, quietly brilliant features that’s been around forever, works almost everywhere, and somehow still feels like a secret.
XCompose is part of the X11 input system. It lets you define compose sequences: short key sequences that produce a Unicode character. Think of it as a programmable “dead key” system on steroids. This can be as simple as programming an ‘E’ to produce a Euro sign or as complex as converting “flower” into a little flower emoji. Even though the system originated with X11, I’ve been told that it mostly works with Wayland, too. So let’s look deeper.
I learnt about .XCompose in my last uni times; it made typing transcriptions in the IPA (international phonetic alphabet) actually bearable. Every other strategy was a mess: copying and pasting was too laborious, and it was too easy to forget something if I used find-and-replace.
I'll share my .XCompose here, to give you guys an idea.
# random misc <dead_acute> <%> : "‰" <dead_acute> <minus> : "⇌" <dead_acute> <apostrophe> : "`" <dead_acute> <h> : "⟨" <dead_acute> <j> : "⟩" <dead_grave> <h> : "͡" <dead_grave> <j> : "͜" # typing Polish in an ABNT2 keyboard <dead_grave> <C> : "Ć" <dead_grave> <c> : "ć" <dead_acute> <D> : "Ą" <dead_acute> <d> : "ą" <dead_acute> <F> : "Ę" <dead_acute> <f> : "ę" <dead_acute> <X> : "Ż" <dead_acute> <x> : "ż" # Subscript numbers <dead_acute> <0> : "₀" <dead_acute> <1> : "₁" <dead_acute> <2> : "₂" <dead_acute> <3> : "₃" <dead_acute> <4> : "₄" <dead_acute> <5> : "₅" <dead_acute> <6> : "₆" <dead_acute> <7> : "₇" <dead_acute> <8> : "₈" <dead_acute> <9> : "₉" # Change vowel height a bit, consonant fortition, tap <Multi_key> <a> <1> : "ɐ" <Multi_key> <e> <1> : "ɛ" <Multi_key> <h> <1> : "ʔ" <Multi_key> <i> <1> : "ɪ" <Multi_key> <j> <1> : "ɟ" <Multi_key> <l> <1> : "ɬ" <Multi_key> <o> <1> : "ɔ" <Multi_key> <r> <1> : "ɾ" <Multi_key> <u> <1> : "ʊ" <Multi_key> <y> <1> : "ʏ" # Change vowel height by a lot, lenition <Multi_key> <a> <2> : "ə" <Multi_key> <b> <2> : "β" <Multi_key> <g> <2> : "ɣ" <Multi_key> <o> <2> : "ɒ" <Multi_key> <p> <2> : "ɸ" <Multi_key> <q> <2> : "χ" <Multi_key> <r> <2> : "ɹ" <Multi_key> <t> <2> : "θ" <Multi_key> <v> <2> : "ʋ" # Vowel fronting, consonant palatalisation <Multi_key> <u> <3> : "ʉ" <Multi_key> <l> <3> : "ʎ" <Multi_key> <d> <3> : "ɟ" <Multi_key> <n> <3> : "ɲ" <Multi_key> <s> <3> : "ʃ" <Multi_key> <z> <3> : "ʒ" # Vowel backing, consonant retroflexion <Multi_key> <a> <4> : "ɑ" <Multi_key> <e> <4> : "ɜ" <Multi_key> <i> <4> : "ɨ" <Multi_key> <r> <4> : "ɻ" <Multi_key> <t> <4> : "ʈ" <Multi_key> <d> <4> : "ɖ" <Multi_key> <s> <4> : "ʂ" <Multi_key> <l> <4> : "ɭ" <Multi_key> <n> <4> : "ɳ" <Multi_key> <z> <4> : "ʐ" # Rounding/unrounding vowels <Multi_key> <o> <5> : "ɤ" <Multi_key> <u> <5> : "ɯ" <Multi_key> <w> <5> : "ɰ" <Multi_key> <j> <5> : "ɥ" # Diacritics, tone <Multi_key> <a> <6> : "́" <Multi_key> <b> <6> : "ʱ" <Multi_key> <c> <6> : "̩" <Multi_key> <d> <6> : "̣" <Multi_key> <e> <6> : "ᵊ" <Multi_key> <g> <6> : "ˠ" <Multi_key> <h> <6> : "ʰ" <Multi_key> <j> <6> : "ʲ" <Multi_key> <n> <6> : "ⁿ" <Multi_key> <q> <6> : "ˤ" <Multi_key> <r> <6> : "˞" <Multi_key> <o> <6> : "̥" <Multi_key> <s> <6> : "̯" <Multi_key> <t> <6> : "̃" <Multi_key> <v> <6> : "̆" <Multi_key> <w> <6> : "ʷ" <Multi_key> <1> <6> : "˩" <Multi_key> <2> <6> : "˨" <Multi_key> <3> <6> : "˧" <Multi_key> <4> <6> : "˦" <Multi_key> <5> <6> : "˥" # Linguistics misc <Multi_key> <a> <7> : "ʕ" <Multi_key> <e> <7> : "€" <Multi_key> <w> <7> : "ʍ" <Multi_key> <n> <7> : "ɴ" <Multi_key> <l> <7> : "ɫ" <Multi_key> <h> <7> : "ɦ" <Multi_key> <g> <7> : "ɢ" <Multi_key> <j> <7> : "ʝ" <Multi_key> <q> <7> : "ʁ" <Multi_key> <r> <7> : "ʀ" <Multi_key> <v> <7> : "ʌ"A few tips I can give people who want to use .XCompose:
- If you often need a character, keep the keystrokes sequence associated with it short.
- Try to be consistent-ish and organised, it’ll help you to remember the sequences.
- Even then, perfect is enemy of good. Don’t go too hard; note for example I didn’t add letters like ⟨æ⟩, ⟨ŋ⟩ or ⟨ð⟩ to the file, all of those are easier to type with AltGr.
- Don’t feel afraid to rework sequences that you find awkward; eventually your muscle memory will catch up.
I fulfilled the first two by using sequences ending in numbers, but note that isn’t the only way to do things. As long as it makes sense for you, it should be fine.
Does this work in any application? And on Wayland?
I noticed that some special keys dont do anything on my keyboard and I couldnt find a way to change the layout to one that has them
I just tested it in Wayland and couldn’t get it to work there.
But in X it works fine for almost every application. Exceptions are usually the same ones who throw hissy fits against dead keys, like games. For those, I typically type the text in a notepad, copy it, and paste it there.




