Thank you for considering contributing to our project! Here are some guidelines to help you get started and ensure a smooth contribution process.
- Fork and Code
- Begin by forking the repository.
- Write your code within your forked repository.
- Pull Request
- Once your contribution is ready, create a Pull Request (PR) to the main branch of the main repository.
- Provide a clear and concise description of your changes in the PR.
- Completion
- That's it! You're done. Await feedback and further instructions from the maintainers.
graph TD
subgraph Forked Branches
fork1["forked branch 1"]
fork2["forked branch 2"]
fork3["forked branch 3"]
end
fork1 --> main["main branch"]
fork2 --> main
fork3 --> main
main --> deployments["documentation deployments (https://owasp-noir.github.io)"]
main -->|release| homebrew["homebrew"]
main -->|release| snapcraft["snapcraft"]
main -->|release| docker["docker (ghcr)"]
# If you've forked this repository, clone to https://github.com/<YOU>/noir
git clone https://github.com/hahwul/noir
cd noir
shards installshards build
# ./bin/noircrystal spec
# Want more details?
crystal spec -vcrystal tool format
lib/ameba/bin/ameba.cr --fix
# Ameba installation
# https://github.com/crystal-ameba/ameba#installationor
just fix- spec:
- unit_test: Unit test codes (for
crystal speccommand). - functional_test: Functional test codes.
- unit_test: Unit test codes (for
- src: Contains the source code.
- analyzer: Code analyzers for Endpoint URL and Parameter analysis.
- detector: Code for language and framework identification.
- models: Contains everything related to models, such as classes and structures.
- noir.cr: Main file and command-line parser.
Noir's analyzer stack is a three-layer design (language engine → route extractor → framework adapter). Before adding a new detector/analyzer, read:
The doc covers how the layers fit together, which engines and extractors already exist, the two supported engine shapes, and a step-by-step walkthrough of adding a new framework (Hertz as the worked example).
Feel free to reach out to us if you have any questions or need further assistance!
Please note that our web page operates based on the main branch. If you make any changes, kindly send a Pull Request (PR) to the main branch.
To ensure a smooth integration of your contributions, please follow these steps:
- Fork the repository and create your feature branch from main.
- Make your changes, ensuring they are thoroughly tested.
- Submit your PR to the main branch for review.
By doing so, you'll help us keep our project up-to-date and well-organized. Your efforts are greatly appreciated, and we're excited to see what you'll bring to the project!
To set up the documentation site locally, follow these steps:
After installing Hwaro, you can serve the documentation site locally using the following Just task:
just docs-serve
# or
just dsThis will start a local server, and you can view the documentation by navigating to http://localhost:3000 in your web browser.
Noir runs a small experimental blog under /blog/ — a space for release deep dives, performance write-ups, framework coverage notes, design rationale, and tips that don't fit in a changelog. Guest posts from the community are welcome — case studies, CI integrations, framework analyses, debugging stories.
Each post is a page bundle under docs/content/blog/:
docs/content/blog/<post-slug>/
├── index.md # English version
└── index.ko.md # Korean version (optional)
The slug becomes the URL (/blog/<post-slug>/). Use lowercase, hyphen-separated words.
+++
title = "Your post title"
description = "One-line summary used in OG cards and the post card on /blog/."
date = "2026-05-17"
tags = ["release", "performance"]
authors = ["<your-slug>"]
template = "blog_post"
+++
Your markdown content starts here.authorsis the taxonomy field — each string must match a key indocs/data/authors.yaml. Multiple authors are allowed (authors = ["a", "b"]).template = "blog_post"is required so the post uses the blog layout instead of the default docs page.tagsare optional but help discoverability.
Add an entry to docs/data/authors.yaml:
<your-slug>:
name: Your Display Name
role: "Guest Writer" # any short role / title you like
bio: "One sentence about you."
image: https://github.com/<gh-handle>.png
links:
- kind: github
handle: <gh-handle>
url: https://github.com/<gh-handle>
# Add as many as you want — twitter, x, mastodon, bluesky,
# linkedin, email, website (fallback for any other URL).The team: true flag is reserved for official Noir maintainers and renders a "Team" badge — leave it off for guest entries. The same registry powers /authors/<slug>/ (your profile page) and the author card on every post you write.
just docs-serve # or: just dsThen open http://localhost:3000/blog/ and http://localhost:3000/authors/<your-slug>/ to see your post and profile.
Open a PR with your post + author entry — same flow as any other change. The 📝 blog label gets attached automatically.