Plugin: 🎨 macOS theme for Joplin

Hi everyone, hereby I like to share my macOS theme for Joplin v2.2.4 and above. Curious to hear what you think. Let me know if you run into any issues.

  • :sparkles: Completely styled UI, including all controls,
  • :last_quarter_moon_with_face: Choose between light, dark, light with dark sidebar or auto (light/dark based on system preferences),
  • :ok_hand: Use native icons (macOS only) or Phosphor icon family,
  • :man_artist: Easy to customise via Joplin preferences.


  • Open Joplin preferences β€Ί 'Plugins', search for 'macOS theme' and install the theme.
  • Restart Joplin. Enjoy!

Sync the Light/Dark-settings under β€˜Appearance β€Ί Theme’ with the value selected under β€˜macOS β€Ί Appearance’ if you experience a flash when switching notebooks.


After installing you can find an extra item named 'macOS theme' in Joplin's preferences. You need to restart Joplin for the changes to apply.

Mac users: If you want to use the native icons, download and install SF Pro from the Apple website here.

No icons?

If you have the 'Icon family'-setting set to 'macOS native (SF Pro)' you need to have SF Pro installed from the Apple website. Note that this only works on macOS-devices.


:warning: Joplin uses styled-components for styling, which makes it incredibly hard to theme the app. A lot of hacky CSS workarounds and !important’s were used. These may cause UI issues with future Joplin releases. Since it's just CSS, your data remains safe and you can easily revert the styles.

Feel free to create an issue or post a message here if you run into issues.


Check the Github repository for more information.

This is a follow-up of this thread.


Thanks, installation works fine.
Minor desc question - * Make sure Theme is set to 'Light' + "Auto light/dark mode based on system theme" is a bit confusing.

Set it to automatic and both preferred themes to light or disable automatic and set it to light?

Thanks, Andre

1 Like

Ah right. Bottomline: it doesn't really matter what the Theme-setting under Appearance is set to. But 'Light' it's the default Joplin theme I use to test my CSS on. But it seems my CSS is overriding the other theme options (Dracula, Nord, etc.) correctly also.

Also, the Joplin-setting Automatically switch theme to match system theme under Appearence doesn't change things when this theme is applied. This theme will ALWAYS apply light or dark mode, depending on what your systems theme is set to.

Edit: Just as a reference, these are the settings that I use (but they don't really matter):

That looks very good, thanks for sharing. I wonder if such a theme could be packaged as a plugin, to make distribution and update easier.


Tahnks a lot, this theme is amazing!

1 Like

I doubt it otherwise the following wouldn't be needed:

Download and install SF Pro from the Apple website here,

Yes I've noticed that, but perhaps we can still reduce friction by packaging the rest of it as a plugin, with a fallback system font. Then as a bonus the user can install this extra font to get a better result.

Yes, the font is one thing. Apple does not allow the font to be redistributed. But this we can easily overcome with a small notice for the user to go and install it from the Apple website.

I've played with the plugin API before, but if I remember correctly I ran into the limitation that the CSS could not be appended to the main window. Also this plugin would require to append CSS into the editor window as well, which I don't know the plugin API is capable of.

Yes I think the API is missing two things:

  • Loading a userstyle.css file provided by the plugin
  • Loading a userchrome.css file provided by the plugin

There's also the fact that you rely on Light theme being set, which probably mean the plugin should be able to set this, and disable the option so that it can't be changed while the plugin is active. I think that's the trickier part.

Well, as mentioned earlier setting the base theme to light is not a requirement anymore. Before there were a few issues when another theme was selected, but this is not the case anymore with this final version. I'll remove it from the installation instructions to avoid any confusion. :slight_smile:

But yes, setting the userstyle.css and userchrome.css would be nice. It would be even better if we could dynamically update it, so that users can change theme variables in Joplin's settings and the userstyle is updated. Maybe just adding an id to the stylesheet would be sufficient.

Not a Mac User but looks Amazing great Work !
I would totally use it on my Mac-Like elementary OS machine too.


Thanks! Well, it's actually quite easy to make this work for non-macOS'es as well. Just re-assign all icon variables to a different UTF-character from another icon font. I think the real challenge is to find an icon font that contains all necessary icons.


Interesting. I might mess around with it once it's fully running on Mac

Looks great, thank you for continuing to work on this and congrats on releasing it! I am switching to your dark mode to try it out :slight_smile:

(FYI, I had a sync issue the other day and because of the way this theme shows it only on hover, I didn't notice the error on my Mac. I simplified the .sidebar.sidebar>div:last-child>div:first-child section to make sure it always displays the sync status. Seems like an awesome addition to hide the normal "successful" sync and then show the full details if there is an issue. Would likely need a new "error" class of some sort, I haven't dug in deep on it.)

(I see that you already accounted for this in the user preferences, for others who want to see sync status always take a look at line ~40).

I had previously done some work to customize the Rich Markdown Plugin. With this release I went ahead and integrated that code to use the same CSS variables as yours (as best as I could) to make it look more seamless. Including since it might be useful to anyone using that plugin.

Code + Screenshots Note: to use this, you need to install the Rich Markdown Plugin AND enable "Add additional CSS classes for enhanced customization" in preferences

.codeMirrorEditor .CodeMirror *{
    /*setting the font to the system font of theme*/
    font-family: var(--g-font-family-system) !important;
    line-height: var(--g-line-height-2);
    font-size: var(--g-font-size-1);

.codeMirrorEditor .CodeMirror * .cm-rm-monospace, .codeMirrorEditor .CodeMirror *  .cm-jn-monospace{{
    /*setting the font to the system font of theme*/
    font-family: var(--g-font-family-mono) !important;

.CodeMirror-sizer, iframe.noteTextViewer {
    /*centers and keeps the max text width easier to read*/
    margin-right: auto !important;
    margin-left: auto !important;
    max-width: 80ch !important;
    line-height: 1.6em !important;

.cm-rm-hr {
    /*makes a `---` look like a line, but leaves the actual text for easier editing*/
    border-top: 1px solid var(--g-separatorColor);
    color: var(--g-separatorColor) !important;
    display: block;
    line-height: 1px !important;
    width: 100%;

.cm-header-1, .cm-header-2, .cm-header-3, .cm-header-4, .cm-header-5, .cm-header-6 {
    /*changes header text color*/
    color: var(--g-headerTextColor) !important;

/*changes header sizes*/
.cm-header-1 {
    font-size: var(--g-font-size-4);
    line-height: var(--g-line-height-5);


.cm-header-2 {
    font-size: var(--g-font-size-3);
    line-height: var(--g-line-height-4);


.cm-header-3, .cm-header-4, .cm-header-5, .cm-header-6 {
    font-size: var(--g-font-size-2);
    line-height: var(--g-line-height-3);

} {
    /*makes the markdown #, ##, ###, etc less noticable*/
    color: var(--g-unemphasizedSelectedTextBackgroundColor)  !important;
    font-size: 70% !important;
    margin-left: -50px;
    max-width: 50px;
    width: 50px;
    overflow: hidden;
    display: inline-block;
    text-align: right;
    line-height: 1.3em;

.cm-variable-2, .cm-variable-3, .cm-variable-4, .cm-variable-5, .cm-variable-6, .cm-s-default .cm-keyword,.cm-keyword,  .cm-variable-2 {
    /*changes list color*/
    color: var(--g-textColor) !important;

.cm-rm-list-token,,,,,, .cm-rm-strong-token, .cm-rm-em-token {
    /*makes markdown-specific things fade back, i.e. _ and ** in bold and italic*/
    color: var(--g-unemphasizedSelectedTextBackgroundColor) !important;
} {
    /*this adds space between the markdown ## and the header*/
    content: '--' !important;
    color: transparent;

.cm-comment, .cm-jn-monospace {
    /*affects the inline code & block color*/
    color: var(--g-secondaryLabelColor) !important;
} {
    /*changes the checkbox color*/
    background: transparent;
    color: var(--g-systemBlue) !important;
},,,,,,,,,,, {
    /*changes links*/
    color: var(--g-linkColor) !important;
    cursor: pointer;

.CodeMirror-activeline-background {
    /* this is hiding the highlighting of your currently selected line*/
    background: transparent !important;

/*Hide URLs */
div:not(.CodeMirror-activeline)>.CodeMirror-line {
    font-size: 0;

div:not(.CodeMirror-activeline)>.CodeMirror-line {
    content: '';
    font-size: 1rem;
} + ~, +,, +  {
    /*puts a strikethrough on completed checklist items*/
    text-decoration: line-through;
    opacity: 0.5;
} {
    /*make markdown tokens for list into dots*/
    color: transparent !important;
    background-color: var(--g-unemphasizedSelectedTextBackgroundColor) !important;
    height: 6px;
    width: 6px;
    border-radius: 50%;
    display: inline-block;
    vertical-align: bottom;
    margin: 0 8px 8px 0;

fyi @CalebJohn in case you're interested


Awesome theme. I am using it now.

I have just added my custom colors to make markdown more appealing:
.cm-header { color: #FAC05E !important; }
.cm-header-2 { color: #3FA7D6 !important; }
.cm-header-3 { color: #ACEB98 !important; }
.cm-header-4 { color: #FF6978 !important; }
.cm-header-5 { color: #FF6978 !important; }
.cm-variable-2 { color: #a0a0a0 !important; }
.cm-variable-3 { color: #666666 !important; }
.cm-variable-4 { color: #444444 !important; }
.cm-keyword { color: #444444 !important; }
.cm-quote { color: #707070 !important; }
.cm-strong { color: #E94F37 !important; }

1 Like

I've now added support for loading chrome and note CSS files from a plugin. It's already on the dev branch if you want to give it a try, or it will be in the next pre-release otherwise. There's a demo plugin there that shows how to use it:

In your case, I think all you'd need to do is setup your build script so that they create the chrome.css and note.css files. I've tried with your theme and it works fine.

Also you can load multiple CSS files like this, so you could even dynamically generate one based on user settings and load it. If you need some info about all this let me know!


That's awesome! I'll take a look at turning this into a plugin.

@uxamanda Yes, there indeed is a user setting to turn off hiding the sync status. I'll make it the default with the next release as sync errors are now easily overlooked. :sweat_smile: Best solution would be to have an error classname on the sync block, which I might give a go eventually.

@h3y1mr0b1n I've started working on making the icons configurable, so that non-mac users can also use the theme. :+1:

@Nifaal Nice to hear you're enjoying the theme!


Looking forward to this plugin. :partying_face:

1 Like

People like you make the world a better place.