Good First Issues in Zig
Explore curated starter issues in high-scoring Zig repositories. Every listed issue belongs to a welcoming repository scored by C-Rank™ on PR merge rates, review responsiveness, and first-timer acceptance.
Arm Issue Sniper for fresh Zig beginner issues
Beginner issues in welcoming S/A-Tier repositories get snatched within 15 minutes. Receive instant alerts on Discord, Telegram, or Email the minute a maintainer opens a new task.
Live Good First Issues (25)
Real-Time Open GitHub IssuesThe below text is copied from the rule ideas megathread. Hello, thanks for your effort on this project! I’m curious if there’s interest in rules for alpha sorting imports. The eslint equivalent is sort-imports. I found a file with 23 lines of imports of both kinds mixed in, and it looked quite bad (though a refactor is probably needed there anyways). I’ve isolated 3 logical changes I would make if I was rewriting that blob: Sorting by package name Before const std = @import("std"); const z = @import("bar"); const a = @import("foo"); After const z = @import("bar"); const a = @import("foo"); const std = @import("std"); But maybe special case std to the top? const std = @import("std"); const z = @import("bar"); const a = @import("foo"); Sorting by file import name const baz = @import("baz.zig"); const bar = @import("bar.zig"); const foo = @import("foo.zig"); After const bar = @import("bar.zig"); const baz = @import("baz.zig"); const foo = @import("foo.zig"); Separating and inserti
Summary Importing a type module brings its main type into scope automatically: import pf.Elem exposing [foo, bar] # Elem, foo, and bar are all in scope Writing import pf.Elem exposing [Elem] is common, especially in generated code. This issue originally proposed treating it as a redundant-expose warning with a formatter autofix. Discussion on Zulip (#ideas > Make import pf.Elem exposing [Elem] a warning) changed direction, so it should be a compile error instead. Design direction Items in an exposing list are always looked up inside the imported module. exposing [foo] means Elem.foo. By the same rule, exposing [Elem] means Elem.Elem, not "the main type again." Nested types may share their parent's name. Elem.Elem is silly but allowed. So the same spelling can refer to a different type, and we shouldn't quietly treat it as a no-op. For import M exposing [X] where M is a type module and X has the same name as the import: Case Result M.X does not exist Error. Elem is already in sco
Setup: mlx-serve 26.8.11 (Homebrew tap), M3 Ultra 96 GB, MiniMax-H3-FL2VA-MLX-Serve-8bit + MiniMax-H3-REF2VA-MLX-Serve-8bit, driving /v1/video/generations over HTTP. What I'm trying to do: clips longer than one window (~10-15 s+) that keep the identities from ref_images — the "family clip" use case: a few reference photos, one scene prompt, 20-30 s out. The caller is a video-generation tool wired into Hermes Agent (which your launch command already knows about), so server-side chaining matters more than it would for a hand-driven client. What happens: chain_windows > 1 together with the REF2VA pack returns: 400: chained windows ride FL2VA keyframe conditioning — the REF2VA pack cannot serve them; load an FL2VA checkpoint That gate makes sense given the two checkpoints. My question before anything else: am I missing a supported way to do this today? Things I considered from the docs/source: Manual continuation via ref_videos: generate window N, subsample its frames, pass them (plu
Summary When mlx-serve dies unexpectedly, MLX Core shows a modal alert and stays stopped. There is no recovery: the server remains down until a human notices the modal and restarts it manually. On a Mac Studio serving the LAN (coding agents, other Macs), a crash takes down every client until someone is at the keyboard. What happens today app/Sources/MLXServe/Services/ServerManager.swift: handleTermination(exitCode:) — when the process exits while .running, it sets .error("Exited unexpectedly") and calls presentCrashAlert(...). presentCrashAlert — a modal NSAlert.runModal() with "Copy Log" / "OK". Dismissing it leaves the server stopped. Intentional stops are already distinguished: stop() nils proc.terminationHandler before terminate(), so only an unexpected exit reaches the alert path. There is no restart anywhere in the app; the only "restart" concept is the manual "Restart Now" banner for settings changes. The building blocks for recovery already exist: lastLaunchedOptions —
While preparing the webassembly.org features-table row (transcription discipline: a cell may claim only what an executed lane or probe showed), extended-const turned out to be the one shipped Wasm 3.0 proposal with no spec-corpus lane behind it: test/spec/spec_assert_runner_wasm_3_0.zig enumerates six proposals (memory64, tail-call, exception-handling, gc, function-references, multi-memory) — extended-const is not among them. Re-derive: git grep -A10 'const PROPOSALS' -- test/spec/spec_assert_runner_wasm_3_0.zig The Wasm 2.0 corpus predates the proposal: scanning every test/spec/wasm-2.0-assert/global/global.*.wasm with wasm-tools print finds no arithmetic in any init expr (i32.add/sub/mul never appear in a constant position). What does exist: 3 unit tests (src/validate/validator_tests.zig — 1 hit, src/runtime/instance/instantiate_const_expr.zig — 2 hits), and the implementation itself works — a probe with an i32.add global init chained off another global plus an extende
Summary Use milliseconds consistently for completed timing rows in CLI timing breakdowns. Currently, each duration independently switches units. This makes a slow phase such as 10.7s easy to miss among nearby values such as 30ms, because the suffixes look similar when scanning the output: ✓ Body Graph Setup 30ms ✓ Body Traversal + Binding 10.7s ✓ Body Type Graph 0ms ✓ Body Call Dispatch 0ms The reporter has two rendering modes: Interactive TTY output commits completed rows while later phases are still running, so it cannot choose a common unit based on durations it does not know yet. Non-interactive --timings output prints the complete breakdown at the end. Choosing one fixed unit avoids different behavior between these modes and does not require buffering, predicting later durations, or rewriting committed terminal rows. Proposed behavior Render every completed phase and subphase duration in milliseconds, regardless of its len
Would it be possible to add an optional idle timeout for loaded models? For example, after 10 minutes without requests, the model would be unloaded and its MLX/Metal memory released. The next request would load it again. This would be useful on Macs with limited unified memory, especially when running large models. For example https://github.com/ggml-org/Llama-macOS supports it via Thanks!
The ADR-0208 measurement (preview1 58/72 interp, 54/72 jit) was taken by driving the official WebAssembly/wasi-testsuite python runner through a zwasm adapter. Upstream carries adapters for other runtimes in its adapters/ directory; zwasm's is not among them. Upstreaming it buys two things: Third-party re-derivability: anyone can measure zwasm's preview1 conformance with the official harness alone — no zwasm-side infrastructure required. Visibility: zwasm appears among the runtimes the official suite knows how to test. Work Write the adapter against the upstream runner's current adapter contract (argv/env/preopen mapping to zwasm run), matching the in-tree runner's semantics (test/wasi/official_runner.zig is the reference for flag mapping). Open the PR upstream (WebAssembly/wasi-testsuite), following their contribution flow. After acceptance, point README's WASI section at the upstream adapter as the independent verification route. Acceptance The adapter is merged upstream, and
eza has hyprlink support, which makes all the entries clickable. It's not something I personally use, but I could see someone else liking it. I would honestly not be interested in implementing this one as I don't need it, but might as well make a feature request.
Pre-flight Checklist I have searched existing issues and pull requests and this has not been requested before. I have/will fill this template with the required information to the best of my ability. I have read the Contributing Guidelines. Request Type New feature or capability Performance improvement UI / app improvement Other Summary When viewing the PKGBUILD diff using Shelly-CLI, the full PKGBUILD file is shown. This makes reviewing the actual diff more difficult depending on the length of the file. I would like an option for a collapsed view where only the changed line(s) with 3 lines above and below as context. Motivation / Use Case Making it easier to see the actual changes at a glance. Reference / Prior Art paru does it perfectly by only showing the changed line(s) with context. Testing / Observations No response Additional Context No response
Semantic: anonymous container in a field type corrupts the parent container's symbol flags Severity: High (default-on unused-decls false positive; dangerous autofix deletes used code) Status: Verified by reproduction Location: src/Semantic/Builder.zig:578 (visitContainer) + src/Semantic/Builder.zig:662-665 (visitContainerField) The bug visitContainer unconditionally sets container-kind flags on whatever symbol is on top of the symbol stack: // Builder.zig:578 self.currentContainerSymbolFlags().set(symbol_flags, true); For a named nested container (const Kind = enum {...}), the var-decl symbol was pushed by visitVarDecl, so the flags land on the right symbol. But an anonymous container appearing as a field's type pushes no symbol — the top of the stack is still the enclosing container. So e: enum { on, off } inside struct Foo sets s_enum on Foo's symbol. visitContainerField then consults the parent's flags to decide whether to visit field type expressions: // Builder.zig:662 const f
Arocc does not include "builtin" pre-processor definitions for Mips targets like _MIPS_SIM. This leads to the translate-c not being able to include type/struct definitions gated behind these definitions (e.g. the goofy struct statfs64 definition for Linux. May depend on ziglang/zig#20690 to make it easier to determine the target's ABI.
Goal Track the remaining builtin work for the Zig compiler. Everything previously listed here that has landed has been removed. See the edit history for the full original checklist. Source of truth: src/build/roc/Builtin.roc, plus src/builtins/*.zig, src/base/LowLevel.zig, src/canonicalize/BuiltinLowLevel.zig, the backends, and src/eval/interpreter.zig. A row is done when the builtin is declared in Builtin.roc, lowered/implemented, supported on every backend and the interpreter, and covered by focused tests. Each item below is labelled: Accepted: the API existed in the old compiler, or follows an established pattern in the current builtins. It needs implementation, not discussion. Needs design: the shape is not settled. Discuss in the linked issue before implementing. API guidance: modern syntax (Try(ok, [Err, ..]), snake_case, where [a.method : ...]), module-specific functions (F64.ln, not Num.log), and one "pit of success" way to do each thing. Prefer Iter over per-collection conve
When I login with phone number it shown error: Successfully logged in error: MissingAccountId And when I tried to switch account codex-auth list warning: auth.json sync skipped: MissingAccountId
Followup from #867 The dx11 backend doesn't wrap uv coords correctly. Reproduction: load demo > Applets > uv_rect the texture should fill the whole area, but is only rendering inside the border (which defines the limits of uv 0-1) I think this is because the shaders don't sample the texture if the uv coords are outside 0-1.
Firstly, thanks for doing this. I'm trying to find a way to continue using https://tend-src.com, and Claude found this project. Quick question: on the readme: SessionStart — the wrapper types the prompt + Enter. Why is that needed? Why not just run claude 'hello world' (still no -p tbc). This is generally how I start my sessions locally
SuperHTML Version 0.6.2 Steps to Reproduce and Observed Behavior <link rel="apple-touch-startup-image" href="..." > is unrecognized and show error (while apple-touch-icon does not) Apple specific attributes are described here Expected Output according to the HTML spec Apple specific attributes should not throw errors
Not sure if this is planned for this minimalist tool, so this is more of an inquiry/suggestion than an issue. We had a server OOM yesterday and had to force reboot the machine. All zmx sessions were gone after the restart, including the metadata (session names, creation time, start directory, etc.). I used to manage background sessions with zellij and it would retain the metadata but often lose previous session outputs (which is fine). Do you think it would be possible to persist some or all of the session data on crashes? Thanks again for the tool! Been really amazing so far.
-- TYPE MISMATCH --------------------------------- This is not a record, so it does not have any fields to access: ┌─ examples/command.roc:21:2 │ 21 │ Cmd.new("env") │ ^^^^^^^^^^^^^^ It is: Cmd But I need a record with a clear_envs field. Here I typed: Cmd.new("env") .clear_envs .env("FOO", "BAR") ... Instead of the correct: Cmd.new("env") .clear_envs() .env("FOO", "BAR") The error message is making a very different assumption about the cause.
Instead of Num.to_str(a) you can now do a.to_str() . The error message should point the user to this new way: -- DOES NOT EXIST -------------------------------- Num.to_str does not exist. ┌─ examples/command.roc:35:32 │ 35 │ Stdout.line!("Exit code: ${Num.to_str(exit_code)}")? │ ^^^^^^^^^^
Inspect.to_str is now Str.inspect. The error should mention this. Current error: -- DOES NOT EXIST -------------------------------- Inspect.to_str does not exist. ┌─ examples/command.roc:18:21 │ 18 │ Stdout.line!("${Inspect.to_str(cmd_output)}")? │ ^^^^^^^^^^^^^^
stack overflow detection May be worth exploring the debug assist module, but this can also be done with a guard value. sync primitives should cooperatively yield if they wake a higher priority task (#907) low power mode where tick interrupt is only triggered when necessary direct task notifications (#907 <- Signal primitive)
osi layer task deletion Currently, tasks spawned by the osi layer can exit but the memory is never freed. Right now, this isn't a problem if one does not init and deinit the wifi driver multiple times. A possible solution would be to create a new low priority task that receives other tasks via a queue and calls rtos.wait_and_free on each. esp wifi: remaining zig wrappers There is still some functionality that we don't have zig wrappers for. esp now bluetooth For a reference implementation, you can look at esp-idf or the rust esp-radio crate. move radio and rtos out of the hal and into a new package that also provides an std.Io implementation (big TODO for the future)
It would be nice to have a panic handler that doesn't crash the entire editor when something panics but something like this: pub fn panic(msg: []const u8, _: ?usize) noreturn { pushError(.wrap(String, &String.fromLatin1(msg)), .{}); if (EngineDebugger.isActive()) { EngineDebugger.debug(.{ .can_continue = false, .is_error_breakpoint = true, }); } else { if (Engine.getMainLoop()) |loop| { if (SceneTree.downcast(loop)) |tree| { tree.quit(.{ .exit_code = 1 }); } } std.process.abort(); } @trap(); } At the very least, please re-expose the panic handler in src/extension/entrypoint.zig like you did with std_options so we can specify a panic handler: pub const panic = if (@hasDecl(extension, "panic")) extension.panic else std.debug.defaultPanic;
#871 introduced FreeRTOS integration for RP2040 and RP2350 ARM targets but there is still more things to do. More Zig wrapping functions At this moment only few FreeRTOS API functions are wrapped in zig module, would be nice to add all of them. More config options in build Right now all FreeRTOS configs are set in FreeRTOSConfig.h file, would be nice to extract some of this option to zig build file. For example: configTOTAL_HEAP_SIZE configSUPPORT_STATIC_ALLOCATION configNUMBER_OF_CORES Allocator selection Current implementation support just on default FreeRTOS heap allocator / strategy: heap_1.c We should allow in build config to select this by configuration option and expose all 5 standard allocators + add extra option where custom zig allocator could be provided. Multicore support Current ports for RP2xxx do not support multicore operation because the following functions remain unimplemented: multicore_launch_core1, multicore_reset_core1, and multicore_doorbell_claim_unused. The mai
Top Zig Repositories with Beginner Issues (10)
Updated Daily via GitHub GraphQLA fast, friendly, functional language.
Immediate Zig GUI for Apps and Games
MicroZig is a toolbox for building embedded applications in Zig.
Native LLM inference server for Apple Silicon. OpenAI + Anthropic API compatible. No Python. Zig backend, Swift frontend macOS app with chat, music, voice, video generation.
A linter for the Zig programming language
Session attach/detach for the terminal
A CLI tool to switch and manage Codex accounts
HTML Validator, Formatter, LSP, and Templating Language Library
A modern ls alternative written in Zig.
Drop-in replacement for `claude -p` that drives the interactive Claude Code TUI inside an in-process zmux PTY session.
How to make your first Zig open-source pull request
Finding approachable Good First Issues in Zig allows you to build real-world software engineering experience. Instead of submitting PRs to abandoned repositories, GetMerged verifies maintainer review speeds and first-timer acceptance rates before you write a single line of code.
Select any issue above to claim it directly on GitHub, or click a repository to inspect full maintainer review turnaround metrics and triage guidance!
Get this week's top welcoming repos + fresh Good First Issues for Zig
Free weekly email, scoped to Zig. No account needed - confirm once and unsubscribe anytime.