Is this possible with ProseMirror?

This is definitely something you can do within ProseMirror, but it’d be complex as one would expect. Let me try to give some pointers.

In my editor I would like to give users the ability to add a translation for each word they type using a custom markup syntax like this: word(translation) or like this: [word]words with spaces/word.

The translation itself will need to be stored somehow, likely as a data attribute on the element.

The first question to think about is whether you would want to use a node or a mark. Both can support storing data within the attrs field.

However, where this gets complicated is that I want the markup itself to disappear when the user hits space after completing it, so e.g. “word(translation)” just becomes “word” maybe with a custom css class to indicate the word has a translation.

Markup to disappear (or to appear) when the user hits space can be accomplished with a mix of decorations and perhaps an inputrule to create the node or mark to store the translation attribute.

Then, whenever the user moves their caret back into the word I want the markup to reappear, e.g. “word” becomes “word(translation)”. It’s this last part I just can’t figure out in Slate js.

This would involve checking on each editor update whether the current selection intersects with a word node or mark. If it does, then you recompute the decorations (or the nodeview) to show (translation).

Overall, I would try grokking the source code of prosemirror-math because they do something similar with the cursor selection to switch between editing latex source and latex render. Best of luck!