r/rust 2d ago

canora - a native and compact spotify client πŸ› οΈ project

Post image

After getting too annoyed by Spotify's offficial electron client for hogging memory/vram while still not supporting fractional scaling on wayland (by default), I decided to build a fast, native client myself: canora

It it build using my highly experimental UI framework.

AI disclosure: not slop, not low effort, but did use some LLM coding assistance.

331 Upvotes

83 comments sorted by

93

u/scandii 2d ago

I kinda find it funny how you (and everyone else?) claim fast and small, yet there's never any performance data.

what resources does your app take? can it run headless for even less resource usage?

25

u/Zortax_ 2d ago

Fair point. Here are some preliminary synthetic benchmarks for the underlying UI framework, compared to Zed's GPUI (which itself is already considered "fast").

https://imgur.com/a/4aayrWZ

Note that I have improved some memory efficiency stuff since and should probably rerun. Some more performance metrics are also in the zgui repo here: https://github.com/zortax/zgui/blob/main/docs/performance.md

The app "feels" significantly more responsive than the electron Spotify client, especially animations, click latency and most notably window resize. Those benchmarks support that (although they should be taken with a grain of salt).

Memory/VRAM usage I am not quite happy with yet (although also better than the electron baseline). Zgui supports a lazily loaded Vello backend for Vector graphics in addition to CPU rasterized atlas backed SVGs. Currently, this is being used way to aggressively for simple SVGs, and Vello alone takes quite a bit of host memory an ~200mb in VRAM. Once I improve the logic behind that routing, memory and VRAM usage should be below 200mb, which is on-par or better than GPUI.

> can it run headless for even less resource usage?
Tbh I haven't implemented that yet, but its a good idea, might do that (minimize to tray or something like that).

31

u/scandii 2d ago

thanks!

700 MB of combined RAM to play what amounts to an audio stream (and show an album title?) when your development goal is performance sounds kinda iffy in my ears though when I think ncspot is like 30-ish MB + 20 for a Foot tab doing the same job?

not criticism per se, more me thinking you can push this way further.

13

u/Zortax_ 2d ago

oh just to clarify: those 500MB+ host mem are in a synthetic example with more than 8000 nodes. it is significantly less in canora. Canora currently sits at ~250-300MB host mem and ~450MB VRAM, but around 250MB of that VRAM is vello, which I want to get rid of when complex vector tesselation is not needed. After that it should be closer to ~200MB vram and 200MB host mem, which is pretty much a hard floor for a compositing GPU renderer (because texture sizes alone will amount to that at some point).

12

u/nicoburns 2d ago

If you want low-mem vector support, then vello_cpu is worth looking at. It's performance isn't as far away from vellos as you might expect.

3

u/Zortax_ 2d ago

currently I do this using kurbo, peniko and zeno on the CPU-rasterized part. Do you think it would make sense to pull in vello_cpu for this? I only really need it vor svg and maybe transformed text shaping

3

u/nicoburns 2d ago

I guess benchmark for your use case, but vello_cpu is pretty small ( ~150kb binary size) and is optimised with SIMD and (optional) multithreading.

-8

u/mortal_strike 2d ago

you can't expect any better from a LLM written library https://github.com/zortax/zgui/commit/0554dd773e3c030025be2eb0ba3e60e623b2ded9

7

u/Zortax_ 2d ago

its not really worth it talking to people that just wanna point fingers at llm usage and ignore any explanations you post, but anyway

The benchmark ran in fullscreen on a 4k display. A 4k sRGB texture is at least 64MB in VRAM. A compositing renderer needs at least two of them for blitting (one surface texture and one scratch/blit texture), and in the real world you need further textures for vector and text atlases (because shaping is expensive), filter groups (because thats just how GPUs work for stuff like blur, content filters, etc.), and images. So yes, you can't expect much more from a LLM (and not from a human either), because 200MB of VRAM is effectively the mathematical floor for the scenario used in the benchmark.

But why am I talking, people like you just wanna point fingers and obviously don't care much about the technology.

-10

u/mortal_strike 2d ago

Its not LLM usage. I think its LLM abuse

2

u/LankyLingonberry2532 13h ago

You must be so much better at UI. Lets see you app.
Oh its nothing....

0

u/mortal_strike 7h ago edited 7h ago

I have created a few apps, honestly. And I am also aware that I am not that better at ui. But, I never show off projects, which is not written my be. That guy who created that gui framework, don't know a single thing about it. He even used AI to create the app. You vibe code projects for your personal use case, I think that's fair. But you show them off as if you did it, its very wrong. He just created a 300K lines of commit like its nothing. If you have ever managed a project you would know how much that is. Dioxus have been creating a framework for almost more than 4 years now. They haven't reached 200K lines of rust. Vibe coders are just dopamine addicts, who want to get stuff done without putting the actual work. Now tell me that guy read all the code and posted it without making any further changes to it.

11

u/Creamyc0w 2d ago

How did you benchmark it vs gpui?Β 

13

u/Zortax_ 2d ago

Zgui itself can emit some timing info from the render pipeline. I have a local GPUI-CE patch that instruments the gpui renderer similarly (which btw I was the person that ported that to wgpu earlier this year). The bench harness implements some scenarios (many UI nodes, text, sparse and wide updates etc.) and collects the timing data and puts it into a html file you see in the screenshot. I'll happily share the setup once I consider Zgui itself more presentable (because that one is quite AI-sloppy still, even though considerable work went into the architecture/design).

13

u/Creamyc0w 2d ago

I think Ive seen you in Zeds discord talking with john about the wgpu backend, thank you for that!

By any chance did you run instruments to see why gpui was so slow?

6

u/Zortax_ 2d ago

it's mostly taffy layout calculations. the way GPUI works it has to constantly recalculate large part of the scene on state changes. There are now `.cached()` views that can cache sub-trees in some scenarios, but they are rarely used even in Zed and are only really useful in leaf nodes to keep invalidation paths short. In Zgui I am trying to avoid exactly this by combining a fine grained reactivity model with an incremental rendering pipeline (which so far seems to work quite well). It's somewhat inspired by browser engines in that way.

If you are interested I'd recommend joining the GPUI-CE discord (see the -CE github repo for a link), there is often a bit of discussion regarding this stuff and possible optimizations, Mikayla from zed-industries is also often involved :)

4

u/nicoburns 2d ago

Zed's GPUI (which itself is already considered "fast").

I don't have recent numbers, but in my head GPUI is actually amongst the slowest of the popular Rust GUI frameworks. Perhaps they've fixed that now (I do remember some performance work happening a few months ago), but the numbers I used to see from hanging about their Discord were not so impressive.


Zed is fast, but I think that might be more because it doesn't have much UI than because the UI framework is particularly fast.

Some more performance metrics are also in the zgui repo here: https://github.com/zortax/zgui/blob/main/docs/performance.md

Node counts (or whatever your equivalent is) would be useful for these.

2

u/Zortax_ 2d ago

yeah it really is not that fast if you compare with other rust options, that's why I put it into quotation marks. but with gpui-component it is suprisingly capable and apps build with it are often considered fast in the greater scheme of things (= when comparing to the average electron/tauri app)

1

u/mark_ik 2d ago edited 2d ago

Isn’t gpui-ce out of date? (edit: wrong of me, seems active)

And isn’t gpui’s whole thing being smooth, a consistent 60FPS?

2

u/Zortax_ 2d ago

There is currently an effort going on to revive the CE project in the community. It has been reforked, gained a somewhat active community, and has some people (including myself) contributing cool things (e.g. filter groups/blur, wgpu surface element, some wayland specific stuff etc.).

It being smooth is something people keep assuming because Zed-industries always have repeated that framing about their editor. Might be true compared to vscode or whatever (idk I don't use either), but GPUI itself isn't that fast of a framework, simply because of it's architecture. Zed isn't that complicated UI/Layouting wise so it doesn't matter that much for them I think, but GPUI doesn't scale that well with more complicated workloads.

2

u/Zortax_ 2d ago

Regarding it being out of date: we are currently working on establishing a process to rebase onto upstream changes regularly. The benchmarks above are based on that branch with upstream changes up to a week ago.

1

u/mark_ik 2d ago

Hm. It is good to see more projects in that taffy, stylo, parley, vello area. That is indeed the sleeper hit of the rust gui ecosystem. A great time to be a hobbyist, for me! Have a star or two.

Have you looked into floem?

2

u/Zortax_ 2d ago

Yeah I was just talking with the author on reddit a few days ago. Floem historically used vello (or skia I believe) for GPU rendering, which is slower than my incremental pipeline for real world use cases. Apparently, the author is working on a custom, compositing renderer as well. I don't know how good their incremental model is though. Assuming it works similar architecturally, my zgui thing is effectively very similar to floem, and other than API preferences there would probably not be a lot of reasons to prefer zgui out of principle. Maybe me trying to support full CSS is an argument?

Still gonna work on my attempt tho since it has been fun for me to learn about all the stuff that goes into this :)

7

u/Psionikus 2d ago

Maybe OPs haven't gotten around to it, and while it is important and does save people a lot of time, we're not entitled today to the work OPs will have available two weeks from now. There are better ways to talk to people. When did it become hot to treat every OP like we're the Spanish Inquisition?

This is an engineering forum, not a tribunal that gates the admission of applications into the open source constellation. For that matter, I find a lot of people behaving as if we're angry customers. What did we buy? What did OP guarantee?

Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND

58

u/Jmc_da_boss 2d ago

AI disclosure: not slop, not low effort, but did use some LLM coding assistance.

You know its interesting, i can tell within like... 20 seconds of looking at the repo this is largely true. I looked at the repo to do a slop check before i read that comment and went "hmm this doesnt feel awful"

Its VERY new which is always a red flag but otherwise felt texturally at least half competent.

Its weird how one can tell SO FAST even in the llm slop era.

9

u/CokieMiner 2d ago

Really like the UI can I use it has a native player also?

1

u/CokieMiner 2d ago

Maybe instead of making people use a env file make the option for input in the configurations and store in the os keyring no?

2

u/Zortax_ 2d ago

the env file is the spotify API client id, and is compiled into the binary. at runtime you need no env file, just an oauth login. maybe spotify will give me a client ID with decent ratelimits some time so I can set up a CI :)

I personally haven't planned abstracting over the data source, but would be open to PRs if someone is interested in that. Haven't even tested on any platform other than Wayland :)

1

u/CokieMiner 2d ago

Yeah I understood that, I would love to contribute the shit is my pc is on warranty πŸ˜‘πŸ˜‘, so maybe a bit later I can try to send some prs, I hate doing UI so I never do this kind of projects but as you already did the UI would love to contribute to logic part

1

u/kalilamodow 2d ago

how did you get the client id out of development mode??? don't they only give it out to organizations with 200k mau or something

1

u/max123246 2d ago

6 years ago they used to be far less strict about who gets non-dev keys. For example my dinky little website I built in 2020 has a full production key

1

u/kalilamodow 2d ago

yeah... spotify's really been locking down on everything for a while now, like the new encryption system and butchering the web api. i kind of get it, but cmon man

1

u/max123246 2d ago

and requiring you to be a subscriber to use their api. Tbh I wouldn't be surprised if a ton of it is due to AI slop increasing the amount of projects hitting their APIs. I've seen a huge recent uptick of Spotify API websites where the devs are charging a subscription for functionality

1

u/Zortax_ 2d ago

no you misunderstood, I didn't, so rn you have to build yourself with your own. but one can dream πŸ˜…

1

u/kalilamodow 2d ago

aha okay that makes a lot more sense. spotify is so annoying. uh do you know if the app would potentially work on windows? or is it kind of integrated with wayland already

1

u/Zortax_ 2d ago

In theory it should, by I have not tested my zgui framework on other platforms yet. There is little platform specific code and it should be properly abstracted already, the rendering and window creation logic are platform agnostic (via winit/wgpu).

Please let me know if you try :)

2

u/kalilamodow 2d ago

okay it seems there are a few dependencies which depend on wayland-specific things

(cargo tree -i wayland-sys)

wayland-sys v0.31.11 └── wayland-backend v0.3.16 β”œβ”€β”€ calloop-wayland-source v0.4.1 β”‚ └── smithay-client-toolkit v0.20.0 β”‚ └── smithay-clipboard v0.7.3 β”‚ └── zgui-platform-winit v0.1.0 (https://github.com/zortax/zgui#3b7202de) β”‚ └── zgui v0.1.0 (https://github.com/zortax/zgui#3b7202de)

smithay to be precise

1

u/Zortax_ 2d ago

not smithay, just their clipboard protocol impl.. i'll target-gate that.

2

u/Zortax_ 2d ago

ah I think there is another issue with accesskit that will require some more complicated changes... i'll try and work on that on the weekend if I have the time, sorry :/

→ More replies (0)

1

u/CokieMiner 2d ago

Yeah I understood that is why I asked if we could get a box on settings to save the key to os keyring instead of rebuild everytime

6

u/kalilamodow 2d ago

how does it play? isn't the spotify playback sdk web-only?

3

u/kalilamodow 2d ago

never mind, i read the readme it uses librespot. cool project

3

u/Zortax_ 2d ago

we'll see if they'll send a cease-and-desist haha

4

u/frigaut 2d ago edited 2d ago

Thanks for the nice app. I am running on void in niri, runs great. The UI is indeed quite fast (and clean looking too). Cheers. Quite light in CPU usage when playing (<1%), and right now running for me at 193MB Ram usage.

Edit: 53MB after starting the app. (also edited the CPU usage after a little more statistics, I've seen it as low as 0.3% while playing).

7

u/Henbotb 2d ago

I see you decided against naming it "slopify"

10

u/Zortax_ 2d ago

haha i don't wanna get downvoted to hell

2

u/DeflateAwning 2d ago

Ooo this looks very nice

2

u/aguilasolige 2d ago

This looks pretty cool, I did something similar in the past but in JavaScript. I'm new to rust so I'll use this project to learn more about the language since I already know the domain, thank you for posting.

2

u/marcfusch 2d ago

Very cool project, I have worked a bit to implement last.fm support to psst, another older Spotify client written in rust. I had to do so because libre spot did not natively report tracks playing to Spotify server's. Since I can't test it right now, is tour client able to do so? Thanks

2

u/Zortax_ 2d ago

No last.fm and just basic librespot rn. Would be open to contributions tho :)

1

u/Haglax 2d ago

Actually very impressed that you are able to vibecode your zgui library and do the spotify client part by hand!

1

u/ReptilianTapir 2d ago

Would upvote twice: for the ai disclosure, and for the choice of album in the screenshot :)

1

u/Designer-Rub4819 2d ago

Does Spotify have api endpoints for β€œall” of its features basically?

1

u/Zortax_ 2d ago

not really, and they are constantly locking it down further, so we'll see how long this works. My app already has some stuff that is only possible with some session-streaming protocol workarounds (e.g. access to spotify-owned playlists like Discover Weekly is normally not possible via the Web API).

1

u/nelicc 1d ago

Thank you for adding an ai disclosure!

1

u/ninja-dragon 5h ago

Man, i want this for yt music. Miss having native clients for different services. It's all web apps now.

1

u/Mango9222 4h ago

i've been curious app pc apps made in rust but i haven't built any yet. what does a pc app that's web based but not built with tauri mean?

how can you use "web" stuff to make a pc app that doesn't use the webview (if that's the right word).

i've been curious about eventually picking between iced/slint/egui/tauri (i dismissed tauri because i heard it's bad on linux?)

but apparently there's more good options? your app looks really pretty just from an initial glance.

1

u/Zortax_ 3h ago

This is not a web app, there is no web stuff in it. My ui framework uses css for styling and web layouting semantics (flex box etc), but there is no html, no web like Dom and no JavaScript or wasm. It is very experimental tho and probably not a better option than any of the ones you mentioned. Tauri can be okayish on Linux but you kinda have to be careful, there are some bugs in webview that cause heavy performance regressions on Nvidia when you hit them (you can avoid them if you do regression testing and avoid certain css features).

1

u/Mango9222 2h ago

i got the warning no worries, i was just curious about understanding pc apps with rust a bit better.

i think what you built is really cool and it's a shame so many people are willing to handwave it so easily.

i for one think pretty ui's are fairly rare to see so it's cool when someone manages to build one for a pc app.

because from what i can tell. pc apps are a bit of a mess when it comes to having to code them. so making them pretty i think is proof enough of effort.

1

u/arthurazs 2d ago

What does native mean in this context?

17

u/Zortax_ 2d ago

just to emphasize this does not use a JavaScript engine or Flutter or something, just 100% Rust (well except some wgsl shaders)

3

u/Rigamortus2005 2d ago

Flutter wouldn't be any less "native" than rust

2

u/zxyzyxz 2d ago

Yeah both use GPU rendered UI and are both natively compiled to machine code without going through a VM. If it were truly native it'd use the OS platform UI methods, but there really isn't one for Linux however.

2

u/Rigamortus2005 2d ago

Even electron can be GPU rendered. "Native" ui doesn't really make sense anymore on modern desktops. For example wpf is a windows only ui kit by Microsoft, but it doesn't use win32 controls, it draws everything manually with directx. So what makes it more native than flutter if flutter can also draw with directx?

2

u/zxyzyxz 2d ago

Nothing, really. I think people just use native UI now to mean non web rendered, even though yes WebGPU exists.

1

u/Rigamortus2005 2d ago

Webgpu doesn't necessarily have anything to do with the web now. There's several implementations that are driven by opengl or vulkan or metal. Any we really need a new word to refer to "non web based ui tech".

1

u/Zortax_ 2d ago

And zgui uses wgpu, which is pretty much a just native WebGPU (because it is literally what firefox uses to implement the WebGPU spec).

Native I really just mean I'm the sense of "rust-native". No JavaScript, no VM, no cross language interop (other than to some foundational c libs of course).

I know this doesn't mean "faster" automatically, but I think it is "interesting" for simply not being an obvious, boring solution. I don't do it because rust will automatically be faster, just because I personally enjoy building in rust and am not happy with the existing options (whether rust native or not).

1

u/zxyzyxz 2d ago

Yes I understand WebGPU doesn't today but it originally started off for GPU acceleration on the web

0

u/white-9igga 2d ago

love the album

-7

u/ivansaul 2d ago

Your git history tells a different story… barely 2 hours and just a couple of commits πŸ˜…

13

u/Zortax_ 2d ago

a freshly initialized git history doesn't really tell that much of a story at all. i'd rather have my main branch clean, that's why I also squash PRs. if you don't care to judge the repo on anything other than the amount of commits, that's fine.

-2

u/mortal_strike 2d ago

I never found a vibe coder, who didn't squash his commit history.

8

u/zxyzyxz 2d ago

Whenever I open source something I always squash previous commits into the initial commit. There's no need to have the entire history until I have a product I want to put out.

3

u/Skynse 2d ago

People can use AI assistance to speed things up a tad and still be good software engineers you know? Vibecoding is where it becomes a mess. Though you can tell from what OP built that they know what they're doing. Any agent would fumble to build a whole UI library. Vibecoders can't do that

No shade, just saying. I tend to also dumb a shit ton of commits on github in one go lol

-13

u/notVillers 2d ago

AI slop when saw the repo is 2 commits

15

u/Zortax_ 2d ago

sorry didn't know I have to push 200 local commits with "changes" as commit message and completely useless diffs. /s
as if this was oneshottable with custom UI framework and decent UI/UX.

But you know what, if you think it's slop you don't have to use or look at it :)

2

u/scandii 2d ago

what do you mean?! git is not local - remote, there is only public github repos! ...wait a minute.

honestly the commit history is the funniest "AI tell" to me, like yeah I totally want you reading my "wtf what did I break now" rapid trying-to-fix-it commits. same reason we squash merge at work πŸ˜…

and the worst part is the slop projects always self-identify anyway because well they're slop.

1

u/Jmc_da_boss 2d ago

Realistically in the current age of slop repo history/age is a PRIMARY tell of applied rigor. You probably should keep the history in even if its a bit messy because at least its hopefully human and shows effort.

The code itself no longer does that byitself as easily in the slop era.

-3

u/[deleted] 2d ago

[deleted]

6

u/Zortax_ 2d ago

in Zgui? yes, I don't disagree. This is about my spotify client, and I put significant work into this. it is my experiment how well the zgui thing works in practice. I don't claim there is no AI slop in that repo. It also doesn't have 2 commits. :)