Skip to main content
Thank you for considering contributing to psys! This guide will help you set up your development environment and understand the project structure.

Development Setup

Prerequisites

Operating System

Linux with ss command (from iproute2 package)

Runtime

Node.js 18+ and npm

Optional

Docker for container detection features

Access

/proc filesystem access for process info

Installation

1

Clone the repository

git clone https://github.com/alexcgomez/psys.git
cd psys
2

Install dependencies

npm install
This will install all required dependencies including:
  • Next.js 15
  • React 19
  • TypeScript 5
  • Tailwind CSS
  • shadcn/ui components
  • React Flow
3

Start the development server

npm run dev
The app will be available at http://localhost:3000.
4

Verify it works

You should see your system’s listening processes and connections in both the diagram and table views.
The development server uses Turbopack for fast hot-reloading. Changes to components will reflect instantly.

Project Structure

Understanding the codebase organization:
psys/
├── app/                      # Next.js App Router
│   ├── api/                  # API routes
│   │   └── connections/
│   │       ├── route.ts      # GET /api/connections
│   │       └── kill/
│   │           └── route.ts  # POST /api/connections/kill
│   ├── layout.tsx            # Root layout
│   ├── page.tsx              # Home page
│   └── globals.css           # Global styles
├── components/               # React components
│   ├── connections-dashboard.tsx  # Main dashboard
│   ├── process-icon.tsx      # Process icon component
│   ├── docker-icon.tsx       # Docker icon component
│   └── ui/                   # shadcn/ui components
│       ├── badge.tsx
│       ├── button.tsx
│       ├── card.tsx
│       ├── table.tsx
│       ├── tabs.tsx
│       └── svgs/             # Service logo SVGs
├── lib/                      # Core logic
│   ├── connections.ts        # Data collection from ss/proc
│   └── utils.ts              # Utilities (cn for classNames)
├── next.config.ts            # Next.js config
├── tailwind.config.ts        # Tailwind config
├── tsconfig.json             # TypeScript config
└── package.json              # Dependencies & scripts

Code Conventions

TypeScript

  • Strict mode enabled: All code must pass TypeScript strict checks
  • Type safety: Use explicit types for function parameters and return values
  • No any: Avoid any type; use unknown or proper types
  • Exports: Use named exports for utilities, default export for components
Example:
// Good
export function getProcessName(pid: number): string {
  // implementation
}

// Avoid
export function getProcessName(pid: any) {
  // implementation
}

React Components

  • Client components: Use "use client" directive when needed (hooks, events)
  • Props types: Define inline types or use TypeScript interfaces
  • Hooks: Follow React hooks rules (eslint-plugin-react-hooks enforces this)
  • File naming: kebab-case.tsx for components
Example:
"use client";

import { useState } from "react";

type MyComponentProps = {
  title: string;
  count?: number;
};

export function MyComponent({ title, count = 0 }: MyComponentProps) {
  const [value, setValue] = useState(count);
  // implementation
}

Styling

  • Tailwind CSS: Use utility classes for all styling
  • cn utility: Use cn() from lib/utils.ts to merge classNames
  • Responsive: Add responsive breakpoints (md:, lg:) where appropriate
  • Dark mode: Use CSS variables from globals.css (e.g., text-foreground)
Example:
import { cn } from "@/lib/utils";

<div className={cn(
  "rounded-lg border-2 bg-card",
  isActive && "border-primary",
  className
)}>
  {children}
</div>

Data Collection

  • Error handling: Always wrap shell commands in try-catch
  • Parsing: Use regex for parsing ss output (see lib/connections.ts:35-36)
  • Normalization: Normalize addresses and ports consistently
  • Performance: Cache Docker lookups when possible
Example:
try {
  const output = execSync("ss -tlnp 2>/dev/null", { encoding: "utf8" });
  // parse output
} catch {
  // handle gracefully - don't crash the app
  return { listeners: [], connections: [] };
}

Testing

psys currently does not have automated tests. Adding test coverage would be a valuable contribution!

Manual Testing Checklist

When making changes, verify:
  • Listeners are displayed correctly in both diagram and table views
  • Connections are drawn properly between nodes
  • Process icons match the detected service (Node.js, Redis, etc.)
  • Docker containers are labeled with the container name
  • Table sorting and filtering work as expected
  • Kill process button sends correct PID to API
  • Error states are handled gracefully (e.g., ss not available)
  • Page auto-refreshes every 5 seconds
  • No console errors in browser DevTools

Testing with Docker

To test Docker container detection:
# Start a Redis container
docker run -d -p 6379:6379 --name test-redis redis

# Start a PostgreSQL container
docker run -d -p 5432:5432 --name test-postgres \
  -e POSTGRES_PASSWORD=postgres postgres

# Verify they appear in psys with Docker icons

Pull Request Guidelines

Before Submitting

1

Create a feature branch

git checkout -b feature/my-new-feature
2

Make your changes

Follow the code conventions above and test thoroughly.
3

Lint your code

npm run lint
Fix any linting errors before committing.
4

Build the project

npm run build
Ensure there are no build errors.
5

Test in production mode

npm start
Verify your changes work in production mode (optimizations enabled).

Commit Messages

Use clear, descriptive commit messages:
  • Format: <type>: <description>
  • Types: feat, fix, docs, style, refactor, perf, test, chore
Examples:
feat: add support for UDP connections
fix: handle IPv6 addresses correctly
docs: update architecture diagram
refactor: simplify address parsing logic

Pull Request Template

When opening a PR, include:
  1. Description: What does this PR do?
  2. Motivation: Why is this change needed?
  3. Testing: How did you test this?
  4. Screenshots: (if UI changes) Before/after screenshots
  5. Breaking changes: Does this break existing functionality?
Example:
## Description
Adds support for filtering listeners by process name.

## Motivation
Users with many processes need a way to quickly find specific services.

## Testing
- Tested with 50+ listeners
- Verified filtering works in both diagram and table views
- No performance regressions observed

## Screenshots
[Attach screenshot of filter UI]

Common Contribution Ideas

Features

  • Support for UDP connections
  • Process filtering and search
  • Export data as JSON/CSV
  • Historical connection tracking

Tests

  • Unit tests for parsing logic
  • Integration tests for API routes
  • E2E tests with Playwright

Documentation

  • Add JSDoc comments
  • Create video tutorials
  • Write troubleshooting guide

Performance

  • Optimize React Flow rendering
  • Reduce polling frequency options
  • Memoize expensive computations

Getting Help

Start with small contributions like fixing typos or improving documentation. This helps you get familiar with the codebase and contribution process.

Code of Conduct

Be respectful and constructive in all interactions. We’re all here to build better software together.
  • Be kind: Respect different perspectives and experience levels
  • Be helpful: Share knowledge and help others learn
  • Be patient: Reviews take time; maintainers are often volunteers
  • Be professional: Keep discussions focused on the code and technical matters

License

By contributing to psys, you agree that your contributions will be licensed under the same license as the project.