Neutralinojs Documentation
repository·main·Indexed 27 days ago
https://github.com/neutralinojs/neutralinojsA lightweight, portable desktop application development framework for building cross-platform apps using HTML, CSS, and JS without Chromium or Node.js. This documentation includes details on integrated libraries such as efsw for file system monitoring and cpp-httplib for C++11 header-only HTTP/HTTPS server and client implementation.
What's inside Neutralinojs
- hwinfo is a modern C++ API designed for retrieving hardware information from system components, including CPU, RAM, GPU, Disks, Mainboard, and Operating System. It supports Linux, macOS, and Windows, though feature availability varies by platform.
Overview of Neutralinojs
mainNeutralinojs is a lightweight, portable framework for building cross-platform desktop applications using JavaScript, HTML, and CSS. Unlike Electron or NW.js, it does not bundle Chromium or Node.js. Instead, it utilizes the operating system's existing webview library (e.g.,gtk-webkit2on Linux) and implements a WebSocket connection for native operations via a built-in static web server. This results in significantly smaller and more efficient applications. Supported platforms include Linux, macOS, Windows, Web, and Chrome.Install and use cpp-httplib
maincpp-httplib is a C++11 single-file, header-only, cross-platform HTTP/HTTPS library. To use it, simply include the
httplib.hfile in your project.Important Limitations:
- Uses blocking socket I/O (not suitable for non-blocking requirements).
- Supports HTTP/1.1 only (HTTP/2 and HTTP/3 are not implemented).
- 32-bit platforms are NOT supported; use at your own risk due to potential integer truncation and security concerns.
#include "path/to/httplib.h"Use Middleware Handlers (Pre-routing, Pre-request, Post-routing)
mainYou can intercept requests at different stages of the lifecycle:
set_pre_routing_handler: Runs before route matching and before the body is read. Use this to reject requests as early as possible. ReturnsServer::HandlerResponse::Handledto stop processing orUnhandledto continue.set_pre_request_handler: Runs after the route is matched (soreq.matched_routeandreq.path_paramsare available) but before the request body is read. Ideal for authentication/authorization checks without buffering large bodies.set_post_routing_handler: Runs after the route handler completes. Useful for adding headers to the response.set_post_routing_handler: Runs after the route handler completes. Useful for adding headers to the response.
// Pre-routing: Reject early svr.set_pre_routing_handler([](const auto& req, auto& res) { if (req.path == "/forbidden") { res.status = StatusCode::Forbidden_403; return Server::HandlerResponse::Handled; } return Server::HandlerResponse::Unhandled; }); // Pre-request: Check route-specific params before reading body svr.set_pre_request_handler([](const auto& req, auto& res) { if (req.matched_route == "/user/:user") { if (req.path_params.at("user") != "admin") { res.status = StatusCode::Unauthorized_401; return Server::HandlerResponse::Handled; } } return Server::HandlerResponse::Unhandled; });Generate missing source files in the development branch
mainThe
developmentbranch does not include automatically generated source files. To generate them, you need Python 3.8 and Perl.First, install the required Python packages:
python3 -m pip install --user -r scripts/basic.requirements.txtThen, use one of the following methods to generate the files:
- Run
make(automatically generates files during build). - Run
make generated_files. - On Unix/POSIX:
tests/scripts/check-generated-files.sh -u. - On Windows:
scripts\make_generated_files.bat.
python3 -m pip install --user -r scripts/basic.requirements.txt make generated_files- Run
Create a basic HTTP Server with cpp-httplib
mainYou can create an HTTP server by instantiating a
Serverobject and defining routes using methods likeGet,Post,Put,Patch,Delete, andOptions. Each handler receives aRequestand aResponseobject. You can use regular expressions for path matching or named path parameters (e.g.,:id).#include <httplib.h> int main(void) { using namespace httplib; Server svr; // Simple GET route svr.Get("/hi", [](const Request& req, Response& res) { res.set_content("Hello World!", "text/plain"); }); // Route with path parameter svr.Get("/users/:id", [&](const Request& req, Response& res) { auto user_id = req.path_params.at("id"); res.set_content(user_id, "text/plain"); }); // Route with regex and captures svr.Get(R"(/numbers/(\d+))", [&](const Request& req, Response& res) { auto numbers = req.matches[1]; res.set_content(numbers, "text/plain"); }); svr.listen("localhost", 1234); }Implement WebSockets (Server and Client)
mainThe library supports WebSockets via the
WebSocketmethod on the server and thehttplib::ws::WebSocketClienton the client.Important Considerations:
- Threading: WebSocket connections occupy a thread for their entire lifetime. For large-scale workloads, configure a dynamic thread pool using
svr.new_task_queue. - Extensions: WebSocket extensions (like
permessage-deflate) are not supported. The server will silently decline them. - Liveness: You can detect unresponsive peers by setting
set_websocket_max_missed_pongs(n). If the client missesnconsecutive pings, the connection is closed. - SSL: Supported via the
wss://scheme.
// Server httplib::Server svr; svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) { httplib::ws::Message msg; while (ws.read(msg)) { if (msg.is_text()) { ws.send("Echo: " + msg.data); } } }); svr.listen("localhost", 8080);// Client httplib::ws::WebSocketClient ws("ws://localhost:8080/ws"); if (ws.connect()) { ws.send("Hello, WebSocket!"); std::string msg; if (ws.read(msg)) { std::cout << "Received: " << msg << std::endl; } ws.close(); }- Threading: WebSocket connections occupy a thread for their entire lifetime. For large-scale workloads, configure a dynamic thread pool using
Implement a file system watcher with efsw
mainTo monitor file system changes, inherit from
efsw::FileWatchListenerand override thehandleFileActionmethod. You can then use anefsw::FileWatcherinstance to add paths to watch and start the asynchronous monitoring process.Key components:
efsw::FileWatchListener: The base class for receiving file events.efsw::FileWatcher: The main engine that manages watches and runs the monitoring loop.efsw::WatchID: A unique identifier returned when adding a watch, used to remove it later.efsw::Actions: An enumeration representing the type of event (Add,Delete,Modified,Moved).
// 1. Implement the listener class UpdateListener : public efsw::FileWatchListener { public: void handleFileAction( efsw::WatchID watchid, const std::string& dir, const std::string& filename, efsw::Action action, std::string oldFilename ) override { switch ( action ) { case efsw::Actions::Add: std::cout << "Added: " << filename << std::endl; break; case efsw::Actions::Delete: std::cout << "Deleted: " << filename << std::endl; break; case efsw::Actions::Modified: std::cout << "Modified: " << filename << std::endl; break; case efsw::Actions::Moved: std::cout << "Moved: " << filename << " from " << oldFilename << std::endl; break; default: break; } } }; // 2. Setup and start watching efsw::FileWatcher* fileWatcher = new efsw::FileWatcher(); UpdateListener* listener = new UpdateListener(); // Add a recursive watch efsw::WatchID watchID = fileWatcher->addWatch( "/tmp", listener, true ); // Start watching asynchronously fileWatcher->watch(); // 3. Cleanup fileWatcher->removeWatch( watchID );Build Mbed TLS using GNU Make
mainTo build the library and sample programs using GNU Make, ensure you have a C99 toolchain and GNU Make installed.
Common commands:
make: Build the library.make check: Run the test suite (requires Python and Perl).make no_test: Build the library without running tests.make generated_files: Generate required configuration-independent files (useful in the development branch).
Environment variables for customization:
SHARED=1: Build shared libraries in addition to static libraries.DEBUG=1: Perform a debug build.WINDOWS_BUILD=1: Use if the target is Windows but the build environment is Unix-like.WINDOWS=1: Use if the build environment is a Windows shell (e.g., mingw32-make).
make # or make checkCompile efsw using Premake
mainTo build
efsw, you must have Premake installed. Use the following commands based on your target platform:Linux/macOS (Makefiles):
- Generate Makefiles:
premake4 gmake - Navigate to the platform directory:
cd make/*YOURPLATFORM*/ - Build:
makeormake config=release(to generate static/shared libs and test app).
Windows (Visual Studio):
- Generate project:
premake4 vs2010
macOS (Xcode):
- Generate project:
premake4 xcode4
Note: A CMake file is also available in the repository, though not officially supported.
premake4 gmake cd make/*YOURPLATFORM*/ make- Generate Makefiles:
Configure Windows Include Order for httplib.h
mainWhen developing on Windows, you must include
httplib.hbeforeWindows.h. Alternatively, you can includeWindows.hfirst if you defineWIN32_LEAN_AND_MEANbeforehand.// Option 1: httplib.h first #include <httplib.h> #include <Windows.h>// Option 2: Define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <httplib.h>Install and use the Neutralinojs CLI (neu)
mainTo develop with Neutralinojs, you need theneuCLI. You can install it globally via npm. Once installed, you can create a new application, navigate to its directory, and run it. To package your application for distribution, use thebuildcommand, which is extremely fast as it requires no compilation.