SkillAgentSearch skills...

Juci

JUCI JavaScript Webgui for embedded devices running OpenWRT

Install / Use

/learn @mkschreder/Juci
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

JUCI Webgui for Embedded Routers

Author: Martin K. Schröder mkschreder.uk@gmail.com

  • Latest version of juci is v2.16.12
  • Juci feed for openwrt with all other packages that juci depends on can be found here: https://github.com/mkschreder/juci-openwrt-feed.git

JUCI architecture looks roughly like this:

JUCI Architecture

JUCI frontend is built with html5, angularjs and bootstrap:

Desktop

JUCI is theme-able and fully mobile-ready (responsive):

Mobile

JUCI is modern web interface developed for OpenWRT-based embedded devices. It is built using HTML5 and angular.js and uses websockets for communicating with a compact and fast lua backend running on the embedded device. You can build both the frontend application and the backend server independently of each other and use them separately.

The OrangeRPCD project which JUCI uses as it's websocket based backend RPC server can be found here: https://github.com/mkschreder/orangerpcd.git.

JUCI Documentation in HTML form can be found here: http://mkschreder.github.io/juci

It is recommended that you start by reading overview of how juci works found here: http://mkschreder.github.io/juci/manual/how-juci-works.html

JUCI Flash and Memory Requirements (actual runtime usage):

  • ~5M flash for full-featured frontend install (including http server)
  • ~160k flash for backend rpc server (revorpcd)
  • 16M ram (revorpcd + lighttpd server)

News

Latest version of juci is 2.16.05.

Release notes:

  • Removed plugins that do not work on OpenWRT.

Release notes version 2.16.03:

  • Moved backend to a specialized juci server and removed dependency on ubus in the backend (see motivation below)

Removing ubus dependency (Feb 2016)

Original juci server was using ubus as it's primary way to organize backend components. This seemed like an awesome idea at the time when juci project was started. Everyone was going to "ubusify" everything. But with time this was starting to cause more pain than good. I will try to explain the implications of "ubusifying" everything below.

Ubus is an excellent system for interprocess communication. However, using it for organizing components of a single application is a very bad idea. It leads to what can best be compared to "microkernel" design. This forces even the most simple tasks such as checking whether user has access rights to some resource to require a serialization and deserialization of parameters (twice!). Micokernel is no different in that it forces everything to be a service. We know from experience that microkernels never really have been successful because their performance sucks for quite obvious reasons (you end up spending most of your time packing and unpacking messages instead of just making simple method calls).

So latest version of juci eliminates all this meaningless rpc message passing and instead implements a single lua backend server that responds to rpc calls from the client and directly provides all necessary services to all backend components that are installed. Instead of all backend components making ubus calls for things like session control, they all now instead just make direct calls into the backend server and this is orders of magnitude more efficient then all the unnecessary internal ubus calls.

Ubus is still supported of course and in fact you should use ubus as means of communicating with other programs running on the system. But for components of the juci backend ubus is no longer used. A single backend server is currently the best solution that I have tried. I have also tried using CGI and lua scripts, but I was not happy with the performance of that solution. It is important to be able to support large number of rpc calls and a specialized juci server makes this very easy to do.

What is JUCI?

If offers you the following:

  • Extremely resource-efficient for your device - your router only needs to run the core functions (which can be written in C!) and the gui itself is running entirely inside the client's browser). You router only computes and sends the minimum information necessary.
  • Full mobile support
  • Easy to work with - the code uses angular.js and html5, making it extremely easy to add new gui elements to the gui.
  • Full control and flexibility - yet many ready-made components: allowing you to pick yourself which level you want to develop on. There are no restrictions to the look and feel of your gui.
  • Dynamic theming - you can switch color themes at runtime.
  • Full language support - allowing for complete localization of your gui. Language file generation is even partially automatic (for html text). Also supporting dynamically changing language on page without having to reload the application. Also featuring quick debug mode for translations where you can see which strings are missing in currently used language pack.

Usage on OpenWRT

Here is how to build a user-mode-linux juci test build. For other architectures these instructions will for the most part be the same (apart from the uml options). UML image will run the whole system as a single executable on your host so you don't need to use any kind of emulator.

# go to your openwrt directory
cd openwrt

# do a full clean (at least delete all your feeds first because we will be overriding things)
make distclean

# add juci feed to feeds conf
echo "src-git-full juci https://github.com/mkschreder/juci-openwrt-feed.git" >> feeds.conf.default

# update your feeds
./scripts/feeds update -a 

# first install all juci packages with force flag
./scripts/feeds install -f -a -p juci

# THEN install all openwrt packages
./scripts/feeds install -a

# select a few top level packages
cat >> .config
CONFIG_TARGET_uml=y
CONFIG_PACKAGE_juci-full-openwrt=y
CONFIG_PACKAGE_orange-rpcd=y
CONFIG_BUSYBOX_CUSTOM=y
CONFIG_BUSYBOX_CONFIG_SHA1SUM=y
^D

# fill out the rest of the selections
make defconfig

# build your image 
make 

# image will be in bin/uml

Before you test your image you need to set up tuntap network device on your host so that you can connect to the gui on the uml image:

# install user mode linux utils
sudo apt-get install uml-utilities

# create a tuntap network device
sudo tunctl -n <your user id>

# set ip address of our tap 
sudo ifconfig tap0 192.168.2.254

# enable ip forwarding 
bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

# add route
sudo route add -host 192.168.2.100 dev tap0

Now you can start your uml image:

cd openwrt/bin/uml/

# starm uml image with tun tap network interface
./openwrt-uml-vmlinux ubd0=/data/software/openwrt-cc/bin/uml/openwrt-uml-ext4.img eth0=tuntap,tap0

Once you are in openwrt do this:

# add orangerpcd user admin
orangectl adduser admin

# set password for juci user admin
orangectl passwd admin admin

# set network ip of openwrt to correct ip 
uci set network.lan.ipaddr=192.168.2.100
uci commit
ubus call network reload

# you will probably need to reboot because tuntap seems to be broken without it 
poweroff

Now restart the uml image again and you should be able to access the gui at 192.168.2.100 using your browser.

Menus will be automatically configured by the juci-full-openwrt package uci-defaults scripts. If you want to use juci in a custom firmware you would typically create a custom metapackage that would only select your plugins and configure JUCI according to your own custom needs.

If you go to your router ip you should see the login screen. By default admin user is used to login but if you don't have password set for admin user you will not be able to login. So then go to the console and set password for admin user or change the user used for logging in by editing /etc/config/rpcd and then do /etc/init.d/rpcd restart.

If you can not login, it could be that you have not installed all juci packages correctly. JUCI requires modified versions of rpcd and uhttpd. In the case that you did not install the feed with "-f" option, you will not be overriding rpcd and so you will not be able to login.

JUCI also includes a nodejs server which you can do for local testing and for forwarding jsonrpc calls to your router during testing (juci-local-server).

Contribution

If you want to contribute to this project, feel free to submit pull requests.

Good to know

Addons can be developed on top of juci by creating package that installs js and css files into the router /www folder and then runs juci-update at postinstall (index.html is actually generated automatically).

In most cases you will never need to modify core juci code. If you need to change behavior of some function, you can always override the public function in javascript without having to modify the original implementation.

Juci uses modified version of uhttpd that can serve gz files with proper content type based on actual gzipped content.

JUCI also uses modified versions of ubus and rpcd on openwrt which you can also install from the feed (using -f option).

Getting started

New: you can now find compiled juci manuals here: http://mkschreder.github.io/juci/

JUCI is designed to work primarily on OpenWRT based systems. Even if you surely can use this code on other systems as well, a lot of functionality is implemented in the backend using OpenWRT tools and packages. So you will naturally need to build your firmware using openwrt to get the most of juci.

To install necessary tools to compile JUCI you can use the file ./scripts/ubuntu-bootstrap.sh. Run it using sudo.

JUCI is a collection of many files

Related Skills

View on GitHub
GitHub Stars408
CategoryDevelopment
Updated4d ago
Forks107

Languages

JavaScript

Security Score

80/100

Audited on Mar 28, 2026

No findings