Use .coffee to config .less in a package


So I am building this UI theme called Graphite-UI. And I am fiddling around with .coffee to let the user have some options. Now I am totally new to coffeescript and I want to know if the following is even possible:
I want to have an option, say a simple boolean, that will change a setting in a .less file. Say we have a toggle for background color of the UI. If it is on, the @background-color in the less files changes to green, if it’s off the color will be red.
I know it is possible to solve it with a addition of a class, but I want to change it in the .less-file so other colors (based and that variable using lighten etc) change accordingly.

What's the risk of not-defining standard syntax variables?

Less has js interpolation. So maybe you could have a less-vars.json file, and read it from less with fs.readFileSync('less-vars.json');? Then you would need to reload your less style every time you write to that file.


Thanks! Let me try that, have to figure out how to access and write to a .json file though.


You can do that from coffeescript easily:

fs = require 'fs'
fs.writeFileSync 'less-vars.json', JSON.parse(object)

The json file can be a file in your project directory


Cool, so I got something like this in my .coffee:

applyThemeColoring = (useColors) ->
  if useColors
    fs = require 'fs'
    data = '{"theme": "blue"}';
    fs.writeFileSync 'less-vars.json', JSON.parse(data)

It triggers the code, but it gives me the permission denied error when trying to access the file. I put it in the project root folder.

EDIT: Also, I think this is super basic stuff, no? Is there a tutorial I should follow, instead of bothering you again? :smile:


The path in the fs.writeFileSync should be relative to the coffeescript file. So assuming your coffeescript file is in project-root/lib/, and the json file is indeed in the project root (project-root/less-vars.json), it should read this:

fs.writeFileSync '../less-vars.json', JSON.parse(data)

note the ../ at the start of the path.

The node api docs should provide you some information, though it could be expanded on in the future. I dont mind the bothering :smile:, but I’ll be away from my pc for the next few hours so you’ll be on your own (and the rest of this awesome community)


Thinking about it, you probably don’t have permission to write to the file because the working directory is set to the atom application’s directory. Try

path = require 'path'
jsonPath = path.join __dirname, '..', 'less-vars.json'
fs.writeFileSync jsonPath, JSON.stringify(data)

Also the JSON.parse was wrong, you should JSON.stringify


Yes this worked, thanks a bunch! Have a good one!


One last thing, trying to run the js in less gives me a big crash.
I’m not familiar with this, and can’t find it anywhere in the less docs. I am getting a ‘unsafe-eval’ error.

@color: `function(){
  var fs = require("fs");
  var data = JSON.parse(fs.readFileSync("less-vars.json"));

  return data.theme;


Atom disables the use of eval and new Function, so embedding JS in your LESS file won’t work. Why not just write out a .less file and include it normally?

fs.writeFileSync 'vars.less', "@color: #{theme};\n"
@include 'vars.less'


That’s clever! Why didn’t i think of that?


oh man… that’s delightful simple. Clever. Thanks!


Oh I so want this! There is some stuff I’ve been able to do in Isotope-UI with just classes and attributes, but it’s suboptimal to say the least.


Yeah, I can also use this in my block cursor package. It’s so much easier than maintaining a <style> element’s sheet :smile:


But how do we actually reload a stylesheet? I can’t seem to find anything in the docs


I’ve been using atom.reload() but somehow that stopped working for me. However it wasn’t ideal anyway, since it completely reloaded atom. What would be better is reloading just the theme.

EDIT: Just changed my UI theme back and forth, and upon changing atom seems to be doing exactly what I need. Reloading just the styles. I should dig around how to trigger that action.


I thought about that, but I’d rather reload just the one style from my package. Reloading the ui theme still makes the window flicker, and worse, on my 3-years-old laptop it makes the entire window completely unresponsive for about 5 seconds…


You can use atom.themes.requireStylesheet:

# remove the stylesheet if it is already loaded
# apply the stylesheet and store the disposable
@myStylesheet = atom.themes.requireStylesheet @myStylesheetPath

If you’d like to see it in context you can look at how I do it: (some calls might be deprecated, I hope I can update it very soon).


Thanks! I’m doing it like this now:

atom.themes.removeStylesheet @myStylesheet
atom.themes.requireStylesheet @myStylesheet

A bit weird this can not be done in atom.styles but only from atom.themes


If I remember correctly using that instead of dispose() fails in the following scenario:

  • apply stylesheet1
  • remove stylesheet1 and apply stylesheet2
  • remove stylesheet2 and reapply stylesheet1
    Stylesheet1 won’t be applied (since somewhere the Theme Manager thinks it is still loaded I believe).

However, a bigger problem is the following commit:

This seems to indicate atom.themes.requireStylesheet is actually deprecated, but Deprecation Cop does not mention it nor can I find what the new way to load a stylesheet is. If it will eventually simply be removed it would be very hard (impossible?) to manually reload stylesheets. Does anyone have an idea what the new preferred method is?