
Trix: A rich text editor for everyday writing - kyledreger
https://github.com/basecamp/trix
======
nmjenkins
Looks decent. The approach taken is the right one: we do something very
similar with the Squire rich text editor
([https://github.com/neilj/Squire](https://github.com/neilj/Squire)) which I
wrote for FastMail's webmail. Basically the browser can't be trusted to do any
formatting itself, which is a slightly depressing state of affairs, especially
as there has been zero improvements in this area for the last 5 years. I guess
it's not shiny enough for browser devs to focus on.

Looking through the code, a few things jumped out that should be looked at:

* Native TreeWalker implementations are buggy in some browsers. In the end we decided it was safer to just implement the bit we needed ourselves (see comment at top of [https://github.com/neilj/Squire/blob/master/source/TreeWalke...](https://github.com/neilj/Squire/blob/master/source/TreeWalker.js)).

* The HTML sanitisation using document.implementation doesn't account for DOM clobbering so is currently bypassable with the right malicious content. I recommend using [https://github.com/cure53/DOMPurify](https://github.com/cure53/DOMPurify) for this rather than writing your own. It's tricky to get all the edge cases right, so better to use something that's been reviewed by several people (and in DOMPurify's case also undergone a formal security review). Again, we use this at FastMail as part of our webmail.

~~~
seagreen
Can you elaborate on not being able to trust the browser for formatting? Is
the idea that web developers should just be able to use <textarea> and not
have to think about it beyond that, and that browsers should provide solid
default <textarea> editor?

~~~
nmjenkins
I mean things as simple as bolding a piece of text. The way to get the browser
to do this for you is to using the document.execCommand method, but the
results are inconsistent between browsers. Worse than that though is stuff
like hitting "enter" on the keyboard – all sorts of crazy stuff happens (new
<span> tags being added, nothing consistent between browsers, generally
doesn't do what you want). We came to the same solution the guys at Basecamp
have: you generally can't trust the browser to get you from state A -> B and
have to do it yourself.

Probably the hardest thing to do is handle copying and pasting, partly because
most browsers give you very little control over this, so you have to resort to
terrible hacks. You also have to decide how much of the formatting in the
clipboard item was "intentional" and how much should be cleaned. I see if you
copy/paste just a word from within Trix, it pastes it as a whole block with
the block's formatting around it. I suspect this may surprise many users who
expect it just to copy the word (the inline bit, not the block around it in
editor parlance). Once you start going down this rabbit hole, you end up
having to do things like take one DOM tree and recursively merge the "edges"
with the adjacent trees to get it to behave as the user expects. I think we do
a pretty decent job with Squire, but I'm sure there are still more edge cases
we haven't covered.

------
danso
Nice to see this particular bit of info high up in the README (though "as seen
in Basecamp 3" would fit well in the Github repo description line):

> _Trix is an open-source project from Basecamp, the creators of Ruby on
> Rails. Millions of people trust their text to Basecamp, and we built Trix to
> give them the best possible editing experience. See Trix in action in the
> all-new Basecamp 3._

Nothing gets me more interested in trying out a JavaScript library than seeing
that it's used in a mainstream production product, _especially_ a money-
making/critical product by very same the company that created/maintains
it...it's a bit of guarantee that the API is relatively mature/won't-go-crazy
and that someone has a vested interest in keeping the library up to date with
changes in the Web. That was why React was so much more appealing to me than
Angular, relative to their respective public release dates...React was already
in production at Instagram and parts of Facebook, whereas I don't think
Angular was in any of Google's main public facing products (i.e. search,
YouTube, Maps)

~~~
kacperpotega
Agree. Although I would have wished to see it in action immediately (on an
example page) without having to clone it to my machine.

Edit: Nevermind, just saw the edit on the comment below :)

------
manigandham
Great timing, we were just looking for a new editor for our project. Since
there are so many choices, here's a list of everything mentioned in this post.

Trix - [https://github.com/basecamp/trix](https://github.com/basecamp/trix) \-
demo here: [http://trix-editor.org/](http://trix-editor.org/) by basecamp and
used in v3, handles files/images well

Squire - [https://github.com/neilj/Squire](https://github.com/neilj/Squire) \-
used in FastMail webmail, better for text than images

ProseMirror - [http://prosemirror.net/](http://prosemirror.net/) \- not great
with images

Scribe -
[https://github.com/guardian/scribe](https://github.com/guardian/scribe) \- by
the Guardian team

CKEditor - [http://ckeditor.com/](http://ckeditor.com/) \- solid and very
customizable, lots of plugins, a little dated in look/feel

Quill - [http://quilljs.com/](http://quilljs.com/)

Summernote - [http://summernote.org/](http://summernote.org/)

wysihtml - [http://wysihtml.com/](http://wysihtml.com/)

Etherpad - [http://etherpad.org/](http://etherpad.org/) \- collaborative
realtime editing

TinyMCE - [http://www.tinymce.com/](http://www.tinymce.com/) \- older editor
but still good

Textbox.IO - [https://textbox.io/](https://textbox.io/) \- new from the owners
of tinymce project

Froala - [https://www.froala.com/wysiwyg-
editor](https://www.froala.com/wysiwyg-editor) \- solid editor, newer features
like drag/drop images, v2 RC3 just released

Redactor - [http://imperavi.com/redactor/](http://imperavi.com/redactor/) \-
we used this in production but quality has gone down, v2 is half the
functionality at 3x the price, not recommended anymore

~~~
sleepyhead
What is the quality problem with Redactor 3?

~~~
manigandham
v2 is their newest release:
[http://imperavi.com/redactor/log/](http://imperavi.com/redactor/log/)

They've removed features like html code view (which is basic and needed since
no editor is perfect), formatting for pasted-in text is worse (even from just
another webpage), image handling is broken (cant resize or even move around
anymore), and lots of stability bugs in general.

~~~
sleepyhead
Sorry I meant v2. I am using v1 but as I just use it for basic formatting I am
not really keen on the high upgrade price. I do think they have done great
work with the editor though. If the editor was important for my app then the
price would be much less of an issue.

Pasting and image handling is probably the most important features for my
clients. Thx for the info.

------
stephentmcm
One thing this gets right that heaps of other WYSIWYG's get wrong is lists.
You can create a proper multi-level list here with order and unordered lists
nested inside each other correctly. This sort of stuff is actually important
for creating accessible documents as things like flowcharts need a plain text
version and nesting lists is a reasonable way of displaying these.

~~~
cben
My litmus test for WYSIWYG lists — which Trix fails — is

    
    
      1. start a numbered list
    
      2. put several paragraphs...
    
         > including some nested block element e.g. quote
    
         ... inside one list item
    
      3. Then continue the numbered list (not from 1!)
    

This is something that's trivial to express in markdown, LaTeX etc but
annoying to impossible with WYSIWYG where being in a list pretends to be a
per-paragraph boolean property. In many WYSIWYGs you can't semantically put
block-level stuff "into" a list item, only fake it by pressing Enter,
cancelling numbering on the new paragraph and increasing indent to align with
list item.

This makes it a nightmare to continue the list afterwards, because actually
I've already closed it. Surprisingly, while many WYSIWYG editors are only
ready to start a new "1\. " list, they do allow me to paste the compound item
into the _middle_ of an existing list without interrupting its numbering.
Sometimes there are other rituals involving liberal consumption of Shift+Enter
and Backspace, dancing with text, and promising my firstborn to be
contentEditable...

Anyway Trix fails it on the simpler task of multiple paragraphs in a list
item. I haven't looked at the code but it seems its content model (at least
strictly enforced) for list items is something like:

\- a single block element (can be a quote or code) \- followed by zero or more
sublist items.

It's good that Trix won't let me increase indent on a paragraph that doesn't
fit its content model. But I need a stronger model for my docs...

Now a quote does allow multiple block content! What happens when I put a quote
inside a list and then add sub-lists inside the quote? Madness:

    
    
      1. foo
      2. | bar
         | baz (this was Enter, not Shift+Enter)
      3. | 1. sublist
      4. | 1. | ququux
         |    | multi-line/paragraph.
      5. | 1. #code () {####
         |    ###...########
         | 1. #}############
      6. | WAT?
      7. | * ulist...
      8. | * | 1. | - he he
    

I'd hope the continuous outer / non-continuous inner numbering is just styling
bugs and not a crazy model?

P.S. A smaller usability issue: how do you make a numbered list with bullet
sublist (or vice versa)? Enter->increase indent->switch to bullets works but
Enter->switch to bullets leaves me with no option to increase indent.
Unnecessarily confusing.

Anyway, lists are why I hate all WYSIWYG with passion as a user. I wish
WYSIWYM with explicitly visible structure (cf. TeXmacs) was more popular.

~~~
cben
Reported the clear bugs (#63, #64). not sure if the list content model is bug
or intentional, though allowing the first line of an item to _be_ a single
quote or code block + the freedom inside a quote does make it questionable
IMHO... (cf. [http://spec.commonmark.org/0.21/#principle-of-
uniformity](http://spec.commonmark.org/0.21/#principle-of-uniformity))

P.S. Squire doesn't seem to allow block content inside lists. Only Shift+Enter
linebreaks.

ProseMirror does allow block content (it defaults to markdown content model);
continuing the numbered list after non-sublist items required the paste-into-
existing-list dance.

Firepad does allow non-item content but doesn't align it like part of the
list. It does tend to continue the numbering afterwards, not sure what are its
exact rules.

None of this is IMHO satisfactory UX. I've observed many people struggle with
lists in any WYSIWYG I've ever seen :-(

------
ipsum2
Since they didn't put a demo up on their site, here's one cobbled from their
documentation:

[http://jsbin.com/cazewaxoje/1](http://jsbin.com/cazewaxoje/1)

~~~
javan
I _just_ added a demo: [http://trix-editor.org/](http://trix-editor.org/)

~~~
aaronbrethorst
Neat, thanks! Literally just this morning I was thinking to myself that I
would give just about anything for a high quality OSS rich text editor capable
of generating terse, correct HTML output.

And here, _not even 24 hours later_ , one just falls into my lap.

~~~
lobster_johnson
There's also ProseMirror [1], which I'm told is very good, and supports
extensions of its document model to support things like embedded objects and
Markdown, and is designed for collaborative editing -- all document operations
are patches that can be sent over the network.

[1] [http://prosemirror.net/](http://prosemirror.net/)

~~~
aaronbrethorst
Cool, thanks for the pointer!

------
amelius
What is the computational complexity of inserting a character into a text
containing N characters, using this editor?

~~~
riskable
This is a very astute observation. When I was developing Gate One I
experimented with something similar for terminals (using contenteditable to
work around issues with keeping elements up-to-date while retaining
formatting) but ultimately ran into severe performance problems. That was
years ago though and browsers have gotten _much_ better at handling
contenteditable with larger amounts of text.

However, the more tags you add to contenteditable elements (i.e. for
formatting) the more work the browser has to do every time there's a page
reflow and there will be a reflow _every time the text changes_. So the more
formatting, the slower (less responsive) it will be.

The workaround for this (no idea if it's used in this editor) is to divide the
document up into lots of individual <div> elements with contenteditable=true
and make sure that all outside-the-view elements are removed or at least
hidden via 'display: none' and merely re-show them on-the-fly as the user
moves about the page. Keeping a page or two above and below the view pre-
rendered can help with responsiveness and you'd also have to make sure to pre-
fill all the document's unseen space with whitespace so that the user can
scroll to any position accurately even if the browser is still retrieving and
rendering that portion of the document.

I came very close to implementing such a solution but ultimately decided on
something else entirely (server-side rendering and a difference-based terminal
update protocol). It's a great idea for an editor and tows the line of, "what
we're supposed to be doing" on the web but ultimately it requires a lot of
complicated code. Far more complicated that one would think at first glance.

~~~
thwd
[http://trix-editor.org/](http://trix-editor.org/)

They don't use contenteditable in the traditional way:

> Trix sidesteps these inconsistencies by treating contenteditable as an I/O
> device: when input makes its way to the editor, Trix converts that input
> into an editing operation on its internal document model, then re-renders
> that document back into the editor.

I find this a fine solution.

------
ayushgta
This looks interesting especially the part about "Trix sidesteps these
inconsistencies by treating contenteditable as an I/O device". We recently
started using froala ([https://www.froala.com/wysiwyg-
editor/v2.0](https://www.froala.com/wysiwyg-editor/v2.0)) and are really happy
with it so far.

~~~
tmikaeld
Also a Froala user, been using CKEDITOR before but switched since Froala
worked better and had a simpler API.

------
m0dest
Interesting naming. The WYSIWYG rich text editor in Google Docs is named Kix.
The engine behind Google Sheets is named Trix.

~~~
braindead_in
Is there an open source alternative to Kix? I've been looking for WYSIWYG
which has the look and feel of a document processor.

~~~
arianvanp
[http://etherpad.org/](http://etherpad.org/)

------
ipsum2
How does this compare to Prosemirror?
([http://prosemirror.net/](http://prosemirror.net/))

~~~
msoad
This doesn't support images as far as I can tell

~~~
sstephenson
Trix fully supports file attachments and image attachments, as documented in
the readme. It includes an inline caption editor for images.

Trix also supports "content attachments" (currently undocumented) which allow
embedding arbitrary HTML as attachments in the document. Basecamp 3 uses this
feature to embed @mentions with avatars, and various oEmbed types, in messages
and comments.

~~~
sealocal
I want to see those "content attachments" as a live demo!

I'm currently using CKEDITOR in a Rails app and inserting HTML "templates."
CKEDITOR renders the HTML and allows the end-user (or content creator) to
modify the HTML while it is rendered inside the contenteditable text area.

------
morokhovets
Has anyone tried to embed Trix into React? How all this custom tags and
polyfills will behave inside react component tree (even though
shouldComponentUpdate will always return false)?

There is [https://github.com/souporserious/react-
trix](https://github.com/souporserious/react-trix) but it looks like it does
nothing at the moment.

------
picardo
This is a Javascript project, but there is no NPM distribution for it.

Edit: yes, it's not a Ruby gem. I stand corrected.

~~~
stephenr
It's also open source. The developers (Basecamp) are obviously deeply invested
in the Ruby stack.

If you want to install it with NPM, you could a create pull request with a
package.json file and some helpful information for the authors about how to
submit to the NPM registry, no?

This _is_ the point of open source software you realise - that you can not
just _use_ the software, but that you can help _improve_ it for yourself and
others.

~~~
voltagex_
Raising an issue on GitHub would be a good first step.

Edit:
[https://github.com/basecamp/trix/pull/32](https://github.com/basecamp/trix/pull/32)

------
pbreit
Please tell me this is a humane alternative to TinyMCE, CKEditor, etc?

~~~
smileysteve
See also [http://summernote.org](http://summernote.org)

~~~
voltagex_
Okay, time to write up an article about all these different WYSIWYG editors.

~~~
petepete
Please include wysihtml5 on your list :)

[http://xing.github.io/wysihtml5/](http://xing.github.io/wysihtml5/)

~~~
voltagex_
Would you like to collaborate on an article?

~~~
petepete
Sorry, I only just saw this message. I'd defintely offer to contribute if
you're writing one alhough I'm not hugely familiar with many (but am with
wysihtml5, quill and CKEditor).

------
timdavila
A couple things I noted while playing with the demo at [http://trix-
editor.org/](http://trix-editor.org/)

* Pressing the <tab> key doesn't insert a tab as I would expect. I'm using Firefox latest on Win8

* The * character doesn't turn into a bulleted list item as I would expect. This is probably more of a nice to have for people use to that behavior in MS Word.

~~~
fokinsean
Same tab issue on latest chrome osx

------
saint-loup
It reminds me of Prosemirror: "By strictly separating its document data
structure from the browser's DOM, ProseMirror sidesteps most of the mess that
is contentEditable, and ensures that the document stays entirely under the
control of the editor." [http://prosemirror.net/](http://prosemirror.net/)

------
rambambam
Last time I saw Basecamp (then 37signals) working on a rich text editor is a
long time ago. What happened to WysiHat? I know it had another developer than
the two guys who made Trix. What I especially liked about WysiHat was the
complete bareness of the toolbar, just plain HTMl links. Is that also possible
with Trix?

~~~
sstephenson
I was involved with the Wysihat project too. What we found is that its
approach, like most other editors', is fundamentally broken. We created Trix
to solve the problem. [https://github.com/basecamp/trix#different-by-
design](https://github.com/basecamp/trix#different-by-design)

I think you'll find Trix's toolbar easy to style however you'd like, but if
not, it ought to be straightforward to implement your own using the API.

~~~
rambambam
Cool, and great work! I had a small e-mail conversation with Josh (forgot his
last name) a couple of years back, I thought he worked on Wysihat alone. I
have seen and tested some RTEs for the web, and I can only imagine how hard it
is to come up with a durable solution. So thanks for Trix and good luck! P.S.
Trix also has a 'royal' connotation to me, because it's short for Beatrix in
The Netherlands. Beatrix being the former queen.

------
akulbe
Why are text editors so popular a project? My apologies if that sounds
anything less than a legitimate question. I'm genuinely curious.

It seems very common to me, over the last several years, to see
$NEW_SHINY_EDITOR, and I wonder why.

Are the alternatives _that_ bad? Or is it just a matter of another dev wanting
to scratch their own itch?

~~~
jacobsenscott
Yes, they are all terrible. I don't know if this will be any better. They all
highlight how bad the web is as an environment to host applications. A rich
text editor - something that is a trivial toy project in any other application
development environment - is impossible to build on the web in 2015.

~~~
sstephenson
It is not impossible. It just takes a lot of time and effort. It took two
developers around 18 months to build Trix.

The readme explains how our approach is different from other WYSIWYG editors.
(Most others are just toolbars that call execCommand.)

~~~
lobster_johnson
Did you look at ProseMirror?
[http://prosemirror.net/](http://prosemirror.net/)

~~~
sstephenson
Yes, of course we've seen ProseMirror. It looks quite nice.

By the time we first heard of it several months ago, the bulk of Trix had
already been written.

------
drikerf
Awesome stuff! Especially the attachment handling. Another more minimal
approach is Squire from Fastmail,
[https://github.com/neilj/Squire](https://github.com/neilj/Squire)

------
ck2
200kb for css+js

have fun with that on mobile where like all browsers, javascript is single
threaded

the reason why we use contenteditable is that it can be done in 15kb and the
browser can do it natively, then you just clean up the resulting code on the
backend

------
cookiecaper
Anyone have an opinion on [http://quilljs.com](http://quilljs.com) ? Haven't
seen it mentioned in this thread yet.

------
nimitkalra
Demo: [https://wells.ee/trix-demo/](https://wells.ee/trix-demo/)

~~~
manigandham
they put the official demo here: [http://trix-editor.org/](http://trix-
editor.org/)

------
travjones
This is totally off topic, but the first thing I thought of when I read "Trix"
was: "Silly rabbit, Trix are for kids!" Anyone else?

On topic: Thanks, Basecamp. I like the minimalism and focus on function of
this project. Contenteditable approaches to formatting text needed some love.
I look forward to trying this out in my next project.

------
automentum
Hard to figure out why no one is doing a plain HTML editor that the humans can
understand and cope with it. That way we stay with the plain text with the
most open formatting standard. A Notepad ++ that is standardized on HTML and
not plain text comes too my mind.

------
lemevi
> CONDUCT.md

Did projects prior to being hosted on GitHub require a Code of Conduct or is
that a new thing.

~~~
yarrel
They don't require it, it's just encouraged.

------
lynnetye
Any Ember users out there? We just wrote an Ember component addon for Trix.
[https://github.com/lynnetye/ember-trix-
editor](https://github.com/lynnetye/ember-trix-editor)

------
steveklabnik
The demo GIFs going around on Twitter a few weeks ago made me really excited
for this.

------
ianstormtaylor
Does anyone know if this would adapt well for real-time use with multiple
people writing at once? Etherpad-style. Or would that need to be architected
differently from the start?

Also, sad that it's in Coffeescript.

~~~
anilgulecha
Nothing sad about it. Just because it isn't $your_favourite_language doesn't
mean it's sad.

------
7kmph
so... does it have vi mode?

------
CamatHN
I really like this. If only it supported ie 9 and below I would use it. Looks
like we are stuck with CK unless anyone can offer other viable, preferably
pretty, solutions?

~~~
axx
It seems like it uses polyfills to solve this problem, no?

From the documentation:

> Eventually we expect all browsers to implement these standards. In the
> meantime, Trix includes polyfills for missing functionality.

------
ShirsenduK
Finally an editor which can replace existing form elements without extra
JavaScript! ContentEditable is wow and all but it doesn't replace textarea,
this does.

------
humbyvaldes
This is cool, one issue thou is that on iOS the select content menu gets in
the way. Not Trix fault but iOS makes these WYSIWYG editors a no go.

~~~
xenihn
Has anyone found a good workaround for this? The best I can do is move the
select content menu after it's loaded, but this looks ugly and is really,
really distracting. Nothing else that I've tried works.

------
ww520
This is very nice. The support for attachment is a surprise bonus. I'm
seriously thinking to incorporate this in one of my projects.

------
truebosko
This a good time to ask about a good, open source text editor that outputs to
Markdown instead of HTML?

~~~
cben
[http://hallojs.org/demo/markdown/](http://hallojs.org/demo/markdown/)
[http://sofish.github.io/pen/](http://sofish.github.io/pen/)
[https://github.com/bevacqua/woofmark](https://github.com/bevacqua/woofmark)
[http://prosemirror.net/demo_markdown.html](http://prosemirror.net/demo_markdown.html)

Haven't seriously used any of those but I'd put my money on ProseMirror as the
most principled one.

------
sealocal
I'm currently using CKEDITOR in a Rails app. I like the cleaner toolbar design
for Trix!

------
l-p
It breaks Pentadactyl external editor feature as every other WYSIWYG editor
do.

This will be a pain to use.

~~~
MarkCole
If _EVERY_ WYSIWYG editor is breaking the plugin. Maybe it's the plugin that
is broken not the editors? Just a thought.

~~~
l-p
Actually, not every editor break it, this is not my real issue with WYSIWYG
editors anyway.

My problem is that I don't want to use them. Unless they use markdown or
another simple formatting language behind the scene, and allow you to switch
to a simple `<textarea>` input, you can't avoid them.

I already have a text editor, I already have a way to generate "rich" text, I
don't need another tool with another set of bindings, quirks, bugs and
incompatibilities. Every editor has its own way to deal with very basic stuff:
when writing a list what happens if you press return twice? Backspace on an
empty element? Tab? You can't know beforehand.

I'm fine with giving tools to non-technical users, but there should be a way
to disable such editors completely so it can adapt to any workflow.

------
z3t4
I don't get these simplistic editors. You just have to learn ten HTML tags to
do the formatting these editors offer.

What would be useful though, would be an editor that supported "design" and
not just text.

~~~
ponytech
It may be used by people that don't even know what HTML is. Good luck teaching
them what a tag is.

------
eccstartup
What about google doc?

------
brentvatne
Very neat -- seems like React for textarea

~~~
brentvatne
Not sure why so many downvotes -- they build an in-memory representation of
the content of the contenteditable, intercept input events to update that
representation, and use that to update the actual dom. Presumably they
wouldn't just wipe out the entire contents each time either, so it's sending
atomic create/update/delete commands to the dom.. So it's like React's vdom
just for contenteditable.

------
jbb555
Oh an editor! Oh... no. It's just a webpage/javascript thing. Not interesting.

