Multiple files and importing libraries

Posted on
  • I have been working with Arduino and MicroPython for a while and just switched to Espruino and nodejs on ESP8266. I am able to upload a file and connect to wifi and do lots of stuff. But there's one thing I cannot figure out:

    MicroPython had a file structure like below:


    as the name suggests is executed on boot, and is the main file where you want to create your main loop. I can create another library and import it from Arduino also has similar structure. How can I do this in Espruino? Can I upload multiple files? If so how?

  • Espruino works a slightly different way by default - it's a bit like 'hibernating'. There's a bit more info here:

    You don't have boot/main/etc - you have one file that you upload from the IDE, however that file can require other files. Usually they'd be online, but you can set up a Project Sandbox directory in settings and then stick your modules in that and include them.

    The IDE only supports editing one file, so when you're getting to the point of having multiple modules you may want to switch to using the command-line tools, and then just use your favorite editor.

  • OK thanks. I am actually using npm library from the console. Pretty powerful. So, if there's only one file I think the best option is to bundle the files and minify into a single file. Actually it's a good idea to have a single file. You can do many optimisations using Grunt and that kind of bundlers.

    Thanks I just wanted to make sure that it is the only way. Now I'm more clear on what I'm going to do. Cheers.

  • I you are bringing the file via the ide with require then it will be minified before it is sent to the board - so in this case using external tools won't be of much benefit.

  • No need to bundle, since at runtime 'nothing' happens, and you gain nothing but the extra step of bundling... or worse, manage the compound export yourself:

    On upload, the IDE goes through the files - recursively - looking (w/ reg expression) for require("moduleName") and upload the files first. And as @Wilberforce points out, does minification if configured to do so... Just make sure you do that not too too too often using Google's minifier - if Espruino still goes that route if configured so - because I got burned with temporary being blocked from Google minification/closure compile service... due to ...overuse of the free option... [Google]

    My approach is now to develop modules by modules inline (similar to what you see in these conversations A and B), and when a module is stable enough, minify it w/ Google's minifier / closure compiler and put it minified into my modules in the local sandbox. Minifying is not just speed, but more so it is space and to provide more variables, since all (most of the time) happens in RAM (yes you can upload into FLASH directly and leaves you with even more RAM for variables...).

    Btw, if you miss multi-document UI in Espruino IDE, edit just your 'main' in Espruino IDE and your modules in your favorite multi-file Editor / other IDE with sourcing directly from your sandbox modules folder. Everytime you upload, your modules get also uploaded - with prior minification - by the very Espruino IDE - and you test your most recent versions of all your sw components.

  • Thanks for the answers. So, if bundling not needed that means I need to upload the file which is the starting point of my app. Like index.js or app.js in a single page app. As I require files espruino will pack them all together and as I understand.

    I don't use the IDE. I use normal text editor and then use command line like below. Works good.

    espruino led.js -p /dev/cu.wchusbserial1420 -b 115200 --board ESP8266_4MB.json

    One thing I don't understand is what happens when I upload another file? It does not seem to overwrite the existing program. For example; I first uploaded led.js which just turns on the builtin LED.

    digitalWrite(2, 1)

    Then I wrote another program which is client.js and does completely something different:

    var http = require("http");
    http.get("", function(res) {
      res.on('data', function(data) {

    What I expect; when I upload the second program, the first one will be overwritten therefore LED would turn off. But it doesn't. It seems it ignores the second program. I need to re-flash the firmware if I want to change the program inside.

  • @cuneyt,

    The term single page (web) app is a term used in context of a browser and means that after initial load of the dhtml, xhr request are made to pull data and html fragments to update the page (in the browser) without reloading it.

    The upload function of IDE does make sure that all required modules are uploaded first into the cache so when it comes to execution, they can be pulled from there.

    If you use the command, I'm not sure what is going on... but I'm sure that you can replace previously uploaded code with new / other code. From context I read that command line tool upload does the same like the IDE: upload requested modules first.

    Command line option has more options...

    To your specific case of code: I may be that your http communication you start conflicts with the upload process. Furthermore, it is non-standard ESP8266 board, so it behaves anyway different than the regular Espruino boards. Give this a shot: pack your code in a function, for example, function myCode() {... and then add setTimeout(myCode,50000); as last line.

    If you use the save option, you have to have an function onInit() { ... } in which you get your code rolling.

  • Hi it's cuneyt. I just lost the access to the email I was registered with. So registered another account. Seems I'll be regular here. I liked this Espruino more than any other firmware. Not sure why it's called Espruino though. It should be called NodeMCU as it actually is the true Nodejs for MCU. Lua firmware should be called something else.

    Anyway, I finally managed to do what I was trying to do. Yes require works in a different way in Espruino. So if I use require to include other files it'll be a mess. Instead I should use uglify.js which just concatenates all files into a single file. Nothing else. Then I can use require for firmware libraries and online libraries.

    Please check my repo below to see how I use terminal. I use espruino npm package. You have all control over the code. It's awesome. Did not really use WebIDE but I'm sure it's using this library in the background in a similar way. It's good for starting but I wanna have more control over my library. And automate things.­http-server

    Here all files in the /src library bundled into a single file and minified. That's it. I just hate to put everything into a single file.

    "uglifyjs src/* --compress --mangle -o ./index.js "

    Put everything into index.js and upload index.js to ESP8266.

    And also I can use package.json to simplify frequently used commands like erasing or flashing the firmware, uploading the code etc.


    function ledStatus(status) {
      digitalWrite(2, status); // is called from httpServer


    function runServer() {
      var http = require('http');
        .createServer(function(req, res) {
          var status = req.url.replace('/?', '');
          if (status === 'on') ledStatus(0) // ledStatus is a function from led.js
          if (status === 'off') ledStatus(1)
          res.end('LED status = ' + status)

    Then when I connect to http://192.168.1.x:8080/?on the LED turns on and turns of when I navigate to http://192.168.1.x:8080/?off

    here is how I use my package.json

    "scripts": {
        "erase": " --port /dev/cu.wchusbserial1420 erase_flash",
        "flash": " --port /dev/cu.wchusbserial1420 --baud 115200 write_flash --flash_freq 80m  -fm dio --flash_size 4MB 0x0000 firmware/boot_v1.6.bin 0x1000 firmware/espruino_esp8266_user1.bin 0x3FC000 firmware/esp_init_data_default.bin 0x3FE000 firmware/blank.bin",
        "reset": "npm run erase && npm run flash",
        "reupload": "npm run reset && npm run upload",
        "uglify": "uglifyjs src/* --compress --mangle -o ./index.js ",
        "upload": "npm run uglify && espruino -p /dev/cu.wchusbserial1420 -b 115200 --board boards/ESP8266_4MB.json -e 'save()' index.js",
        "screen": "screen /dev/cu.wchusbserial1420 115200"
  • @aliustaoglu - before @cuneyt, sorry not having responded to you then...

    I see the benefit of this approach, because you can just just any IDE to develop your code and then with a target specific script upload all code... and even automate it.

    In your scripts you include also the flashing of the firmware. You do need that only when a new version becomes available. A board once flashed with the firmware needs only the javascript application part to be uploaded. I see not all of the package.json but I assume you consider that when using it.

    Furthermore, you can universalize this package.json/scripts by de-version the firmware and have a link to the most recent one. For the application part you already do this by convention to always use index.js. Version and board specifics have of course be taken care of.

  • @allObjects
    Yes I've been using this method all the time. It works pretty fine. I like using terminal and vscode so this approach suits me best. Also I like to have multiple files so I can make my system quite modular.

    I've also created an npm package. If you install this npm module globally you can create this boilerplate easily and then change it as you desire and have this structure. It supports both ESP8266 and ESP32. Module is here:­reate-project

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Multiple files and importing libraries

Posted by Avatar for cuneyt @cuneyt