M
Medium Engineering
medium.engineering · Company blog · on HN since 2016
Medium's engineering team writes about the editor, microservices, hiring, and bugs like the disappearing Polish S.
What HN saysHN commenters call the ContentEditable post a classic technical explanation and link the Polish S bug, and cite its editor design and microservices.
55HN people shared it
20linked it in comments
40stories submitted
662story points
3 months agolast shared
2016people per year2026
Most-shared posts
- 1Why ContentEditable Is Terrible – Or: How the Medium Editor Works16 people · 13 points · first shared 2016 · discussion on HN
- 2The curious case of the disappearing Polish S (2015)8 people · 293 points · first shared 2016 · 44 comments on HN
- 3Experiences introducing microservices at Medium6 people · 9 points · first shared 2018 · discussion on HN
- 4The days of .dev domains for testing code are over5 people · 86 points · first shared 2017 · 93 comments on HN
- 5Medium open sourced their hiring process5 people · 12 points · first shared 2016 · 1 comments on HN
- 6Mapping Medium’s Tags – Medium Engineering2 people · 5 points · first shared 2018 · discussion on HN
- 7Medium's Engineering Interview Rubric2 people · 3 points · first shared 2017 · discussion on HN
- 8Typography is impossible (2016)1 people · 219 points · first shared 2022 · 63 comments on HN
- 9GraphQL Server Design Medium1 people · 5 points · first shared 2018 · discussion on HN
- 10Microservice Architecture at Medium1 people · 4 points · first shared 2018 · discussion on HN
- 112 Fast 2 Furious: migrating Medium’s codebase without slowing down1 people · 4 points · first shared 2018 · discussion on HN
- 12Evolution of the Medium iOS App Architecture1 people · 2 points · first shared 2022 · discussion on HN
- 13Counting your followers. How Medium counts your followers1 people · 1 points · first shared 2020 · discussion on HN
- 14Code Reviews at Medium1 people · 1 points · first shared 2021 · discussion on HN
- 15Engineering Stories Behind the Medium Daily Digest Algorithm: Part 11 people · 1 points · first shared 2025 · discussion on HN
What HN people wrote when they linked it
jkaptur · 2016-08-31
Here's a great technical explanation of the problem: https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
jitl · 2022-06-21
Writing a ContentEditable editor means learning the internal state machines and undocumented behaviors of every browser you support. There are many articles online about ContentEditable / rich text editing. This one is a classic https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
The major issue for both Android and CJK input is dealing with “composition” of characters by an “input method editor”. https://en.m.wikipedia.org/wiki/Input_method
In English, usually it’s okay to assume one key press event = one letter input. The opposite is true on Android generally, and for CJK languages on all platforms. These use input systems (like handwriting) where keypresses never occur, or many keypresses compose to produce one character. There are also new rules for IME composition input like “you can’t touch the DOM or change the selection during composition or the input will cancel and your user will be mad”. It turns the problem from “Hard” difficulty to “Nightmare” difficulty.
The baffling thing on Android is that each keyboard (Gboard, Samsung Keyboard, Swiftkey, Simeji, Sogou, Naver) have different composition behaviors with different event patterns… and GBoard’s ENGLISH input is probably the most strange! It composes whole English words like they were Chinese characters, and it wants to compose SO badly it will move text selection from wherever the user tapped to the nearest English word. And as an added bonus on Android only, the browsers selection APIs…
jiggawatts · 2026-01-03
> Architecturally monolithic Web apps use GraphQL all the time.
Sure, but a significant motivation for using GraphQL is to stitch together a bunch of microservices into a cohesive API for the front end.
My comment about Medium using microservices was just an informed guess, but a good one. They started migrating from a monolith to microservices back in 2018: https://medium.engineering/microservice-architecture-at-medium-9c33805…
Is it a coincidence that that's around the time frame that I noticed the Medium web site becoming slower than it used to be?
miki123211 · 2023-07-10
Poland seems to be generating these kinds of edge cases all the time.
For example, see also https://medium.engineering/the-curious-case-of-disappearing-polish-s-f…
jake-low · 2022-12-12
There are a number of rich text editors that model documents as a flat array of characters and a separate table of formatting modifiers (each with an offset and length). Medium's text editor is one of them. This post [1] on their engineering blog introduced me to the idea, and I think it's a good starting point for anyone interested in this topic.
ProseMirror (a JavaScript library for building rich text editors) also employs a document model like this. The docs for that project [2] do a good job of explaining how their implementation of this idea works, and what problems it solves.
[1]: https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
[2]: https://prosemirror.net/docs/guide/#doc
girvo · 2022-10-11
https://ckeditor.com/blog/ContentEditable-The-Good-the-Bad-and-the-Ugl…
Or
https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
Are two that I remember reading... nearly 10 years ago, holy hell can someone please make time slow down? Which discuss the common API pitfalls with `contenteditable` -- though I've no idea how painful it is in 2022. Could be a lot better now?
math-dev · 2022-08-21
You may not agree, but from a technical / UX perspective it is impressive - the rest of their UI platform sucks but I think their editor is top notch
https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
abdusco · 2021-11-24
Not really. It revolves around textarea not allowing rich inputs. That includes @-mentions, /-commands, block-based content builders etc. Textarea is laughably basic when it comes to adding interactivity to it, so the only solution is to use contentEditable[0][1], which is very difficult to work with or roll your own input[0], which makes OP angry.
[0]: https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
[1]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/contentEd…
billconan · 2021-09-22
I have read an article that contenteditable is not ideal
https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
ZenPsycho · 2018-12-06
manipulating JSON (really, just plain native language objects) is way more straightforward than manipulating the XML dom. The purpose of formats like this is to make inexpressible the kinds of documents that result in difficult to untangle bugs, and frustrating UI behaviour. See this article about how Medium's editor was designed for some essential background of the motivation for this JSON format
https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
mindcrime · 2018-10-10
You can create whatever arbitrary naming convention you want for internal networks, and use either hosts files or your own private DNS server to resolve those names. But if your scheme overlaps with something that's published publicly, it's probably going to cause problems at some point.
There's a little bit of info in some RFC's about special / reserved names, which are dedicated to certain special uses. See, for example:
https://tools.ietf.org/html/rfc6761
https://tools.ietf.org/html/rfc2606
In years past, a lot of people would just pick a tld that didn't exist and then use that for internal domain names. That was probably safe back when new TLD's came into existence very infrequently. In this day and age, TLD squatting is a risky proposition, as seen here:
https://medium.engineering/use-a-dev-domain-not-anymore-95219778e6fd
mark-r · 2017-12-21
According to this recent post Google is in charge of the master list that all the other browsers use. Expect the .dev domains to stop working on those other browsers shortly.
https://medium.engineering/use-a-dev-domain-not-anymore-95219778e6fd
yuchi · 2017-07-13
Sorry but it’s just using the standard contenteditable attribute, which works terribly, see https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
betageek · 2017-07-13
Also the editor that will output the most inconsistent HTML across browsers. There's a reason all those other editors try and fix contenteditable (and are therefore > 1k), for more info see https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
Ralfp · 2017-04-17
Theres also good article from Medium's engineering titled "Why ContentEditable is terrible":
https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
polm23 · 2017-04-17
Here's that Medium post: Why Content Editable is Terrible
https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48…
prezjordan · 2017-04-05
This happened at Medium [0] because they hash paragraphs to a 4-digit hexadecimal string, and ad blockers would hide things like "#ad01", "#ad02", etc.
[0]: https://medium.engineering/the-unluckiest-paragraphs-751dd36d2d30
ilyanep · 2016-05-18
Some more:
The disappearing Polish S https://medium.engineering/the-curious-case-of-disappearing-polish-s-f…
System Shock "A story of a 25-year-old font coming back with a vengeance" https://medium.com/designing-medium/system-shock-6b1dc6d6596f#.um2jxyl…
mananaysiempre · 2021-06-15
One of unresolved questions of rich text in my mind is what to do with these markup “codes”, explicit or hidden, because while the (usually) nested open/close structure is a non-terrible way for describing formatting in plain text, it is IMO a completely unnatural model (mental or programmatic) of describing rich text by itself, not backed by marked-up plain text. This is apparent in abstraction leaks like the one you describe, but it also has a way of making your life really miserable as soon as you want to reason about transformations of documents, like in a collaborative editor or just a HTML-based editor.
In fact, both Google Wave (IIRC, not going to look up the reference right now) and the Medium editor (https://medium.engineering/why-contenteditable-is-terrible-122d8a40e48… represent inline formatting as a bucket of non-nested “spans”, because while this still doesn’t yield a unique representation of what you want to call rich text, it gets much easier to pick a canonical representative for each class of equivalent representations that doesn’t get completely upturned by localized editing operations.
Even the text editor example in the GoF book just assigned each character a (shared, CoW) style object... Does anyone actually do it this way?
adamzochowski · 2021-04-08
There is also a whole slew of issues with Polish characters. Polish keyboard setup relies on "right-alt" and a letter to get it's diacritics variation. Ie:
'ą' is 'right-alt'+a
Windows for backwards compatibility reports 'right-alt' as 'alt+control'.
Many applications developers assign key combos with no negative checks. So 'ctrl-s', typically used for save gets triggered when user wants to type 'ś'. To repeat, "right-alt"+"s" is reported as "alt"+"control"+"s", which triggers crappy "control"+"s" checks.
Similar scenarios happen many places that check for 'alt'+'letter' without checking if control also is not pressed.
Microsoft thread for team user voice issues on this https://microsoftteams.uservoice.com/forums/555103-public/suggestions/…
or Medium's developer talking about 'ś' and 'ctrl'+'s'.
https://medium.engineering/the-curious-case-of-disappearing-polish-s-f…