So I downloaded noStrudel source code and managed to turn it into a desktop app with help of Tauri and Rust. I did this also to Coracle client and it worked as well.
"Tauri is an open-source software framework designed to create cross-platform desktop applications on Linux, macOS and Windows using a web frontend. The framework functions with a Rust back-end and a JavaScript front-end WebView using rendering libraries like Tao and Wry."
- Tauri_(software_framework)
Here is Linux x86-64 version of the binary if you just want to try it: nostrudel.gz (3.4MB)
There are no guarantees. You'll probably need at least something like these libraries: libssl, libgtk-3, librsvg2, libwebkit2gtk-4.0-37.
I also have .deb package: nostrudel_0.1.0_amd64.deb (3.5MB)
![]() |
Running local relay at ws://localhost:4869 will get detected automatically by noStrudel and allows you to enable "Nostr Relay Tray" from relay settings to give you a local cache with better performance and larger capasity than IndexedDB has. |
You may not need yarn and might be able to get away just using npm but that's what the project is using, so...
npm install --global yarn
Clone the repo:
git clone https://github.com/hzrd149/nostrudel.git
cd nostrudel
yarn install
Quick test to see that everything works as they should
yarn dev
Install Tauri dependencies
https://tauri.app/v1/guides/getting-started/prerequisites
This is for Debian based systems:
sudo apt update
sudo apt install libwebkit2gtk-4.0-dev \
build-essential \
curl \
wget \
file \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev
Install Rust build toos:
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
Now we configure the app with help of these instructions:
https://tauri.app/v1/guides/getting-started/setup/vite
Edit vite.config.js and add these items.
// prevent vite from obscuring rust errors
clearScreen: false,
// Tauri expects a fixed port, fail if that port is not available
server: {
strictPort: true,
},
// to access the Tauri environment variables set by the CLI with information about the current target
envPrefix: ['VITE_', 'TAURI_PLATFORM', 'TAURI_ARCH', 'TAURI_FAMILY', 'TAURI_PLATFORM_VERSION', 'TAURI_PLATFORM_TYPE', 'TAURI_DEBUG'],
build: {
// don't minify for debug builds
minify: !process.env.TAURI_DEBUG ? 'esbuild' : false,
// produce sourcemaps for debug builds
sourcemap: !!process.env.TAURI_DEBUG,
},
In the end it should look something like this:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
// https://vitejs.dev/config/
export default defineConfig({
base: process.env.VITE_BASE ?? "/",
clearScreen: false,
server: {
strictPort: true,
},
envPrefix: ['VITE_', 'TAURI_PLATFORM', 'TAURI_ARCH', 'TAURI_FAMILY', 'TAURI_PLATFORM_VERSION', 'TAURI_PLATFORM_TYPE', 'TAURI_DEBUG'],
build: {
target: ["chrome105", "edge89", "firefox89", "safari15"],
minify: !process.env.TAURI_DEBUG ? 'esbuild' : false,
sourcemap: !!process.env.TAURI_DEBUG,
},
plugins: [
react(),
VitePWA({
registerType: "prompt",
workbox: {
// This increase the cache limit to 3mB
maximumFileSizeToCacheInBytes: 2097152 * 1.5,
},
manifest: {
name: "noStrudel",
short_name: "noStrudel",
description: "A sandbox for exploring nostr",
orientation: "any",
theme_color: "#8DB600",
categories: ["nostr"],
icons: [
{ src: "/favicon.ico", type: "image/x-icon", sizes: "16x16 32x32" },
{ src: "/icon-192.png", type: "image/png", sizes: "192x192" },
{ src: "/icon-512.png", type: "image/png", sizes: "512x512" },
{ src: "/icon-192-maskable.png", type: "image/png", sizes: "192x192", purpose: "maskable" },
{ src: "/icon-512-maskable.png", type: "image/png", sizes: "512x512", purpose: "maskable" },
],
// TODO: actually handle this share data
// @ts-ignore
share_target: {
action: "/share",
method: "GET",
enctype: "application/x-www-form-urlencoded",
params: {
title: "title",
text: "text",
url: "url",
},
},
},
}),
],
});
I needed to edit node_modules/react-qr-barcode-scanner
package.json file and upgrade some packages:
react: "^16.13.1", => "^18.2.0"
react-dom: "^16.13.1" => "^18.2.0"
@types/react: "^16.9.35", => "^18.2.0"
@typescript-eslint/eslint-plugin: "^2.33.0" => "^7.11.0",
@typescript-eslint/parser: "^2.33.0", => "^7.11.0"
eslint: "^7.0.0", => "^8.56.0"
Get back to project root and create the Rust Project:
npm install --save-dev @tauri-apps/cli
Add tauri to package.json scripts:
"scripts": {
"tauri": "tauri"
}
It should end up looking something like this:
{
"name": "nostrudel",
"version": "0.39.0",
"private": true,
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/hzrd149/nostrudel"
},
"scripts": {
"start": "vite serve",
"dev": "VITE_APP_VERSION=production vite serve",
"build": "tsc --project tsconfig.json && vite build",
"format": "prettier --ignore-path .prettierignore -w .",
"analyze": "npx vite-bundle-visualizer -o ./stats.html",
"build-icons": "node ./scripts/build-icons.mjs",
"tauri": "tauri"
},
"dependencies": {
"@cashu/cashu-ts": "^0.9.0",
"@chakra-ui/anatomy": "^2.2.2",
"@chakra-ui/breakpoint-utils": "^2.0.8",
"@chakra-ui/icons": "^2.1.1",
...
Scaffold a minimal Rust project that is pre-configured to use Tauri
$ npm run tauri init
> nostrudel@0.39.0 tauri
> tauri init
✔ What is your app name? · nostrudel
✔ What should the window title be? · noStrudel
? Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" f✔ Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" file that will be created? · ../dist
✔ What is the url of your dev server? · http://localhost:5173/
✔ What is your frontend dev command? · npm run dev
✔ What is your frontend build command? · npm run build
Then you have to edit src-tauri/tauri.conf.json
and change the bundle identifier. I changed it to ninja.noStrudel
"identifier": "ninja.noStrudel",
Now you can test everything by running.
npm run tauri dev
...or you can build your binary with:
npm run tauri build
If everything went well, you should have binary in ./src-tauri/target/release/nostrudel
and AppImage where it tells you. I did have problems with AppImages and they are pretty huge so you probably want to just stick with the binary version. If everything didn't go well ...well, good luck then.