First off, thanks for taking the time to contribute! 🎉
VortexPanel is built with Python/Flask backend and Alpine.js frontend. It's designed to be approachable — no Node.js build step, no complex toolchain. If you can run python3 app.py, you're ready to contribute.
- Check existing issues first
- Use the Bug Report issue template
- Include: OS and version, what you did, what happened, what you expected, any error messages from
/var/log/vortexpanel/error.log
- Use the Feature Request issue template
- Describe the use case, not just the implementation
- Check the roadmap in the README — if it's already listed, +1 the existing issue instead of opening a new one
- Fork the repo and create a branch:
git checkout -b feature/your-feature-name - Make your changes (see Code Style below)
- Test on a real or virtual Linux system — the panel must start with
python3 app.py - Open a PR against
main— describe what you changed and why - Reference any related issues with
Closes #123
git clone https://github.com/BrowserlessAPI/VortexPanel.git
cd VortexPanel
pip install -r requirements.txt
python3 app.pyPanel runs at http://127.0.0.1:8888. Admin password is printed on first run and saved to admin_password.txt.
- Python 3.8+ compatible
- Follow existing patterns in
panel/routes/— each feature is a Flask Blueprint - Shell commands via the existing
sh(cmd)helper (returns stdout string) orsh3(cmd)(returnsstdout, stderr, returncode) - Every route must check
if not req(): return jsonify({'ok':False}), 401first - Multi-distro support via
get_os()fromos_utils.py— never hardcodeapt-get; usepkg_install()instead - Use
panel_cache.set(key, value, ttl)for expensive read-only endpoints
- No npm, no build step — plain HTML/JS/CSS only
- New pages go in
web/templates/index.htmlas<div x-show="page==='yourpage'" x-data="yourPage()"> - New Alpine components go in
web/static/js/app.js - Every page component's
init()must include:document.addEventListener('vortex-logged-in', () => { this.init(); }); - Use existing CSS variables from
web/static/css/theme.css— no hardcoded colors - Use
.modal-overlayclass for modals/drawers (not inlineposition:fixed— causes stacking context issues) - Avoid
x-showwithoverflow:hiddenparents — use.modal-overlayclass which is defined at root level
- Create
panel/routes/your_module.pywith a Blueprint - Import and register it in
app.py - Add a nav item in
web/static/js/app.jsin thenavItemsarray - Add the page HTML in
web/templates/index.html - Add an
async init()with thevortex-logged-inlistener
- 🧪 Testing on RHEL-family distros (AlmaLinux, Rocky, Fedora, Oracle, CentOS Stream, CloudLinux) — firewalld path specifically
- 🌍 Translations — panel strings are in the HTML templates
- 📖 Documentation — setup guides, module how-tos, video walkthroughs
- 🐛 Bug fixes — especially on multi-distro edge cases
Be respectful. See CODE_OF_CONDUCT.md.