Code Style
March 30, 2026 ยท View on GitHub
Coding conventions for NornicDB.
Go Formatting
Use gofmt -s or goimports:
gofmt -w -s .
goimports -w .
The repository also includes a tracked pre-commit hook at .githooks/pre-commit
that automatically runs gofmt -w -s on staged Go files before the commit is
created. Install it once per clone:
make install-hooks
Naming Conventions
Files
- Lowercase with underscores:
db_test.go - Test files:
*_test.go - Platform-specific:
*_linux.go,*_darwin.go
Variables
// Local variables: camelCase
userName := "alice"
// Package-level variables: camelCase or CamelCase
var defaultTimeout = 30 * time.Second
// Constants: CamelCase
const MaxRetries = 3
Functions
// Exported: CamelCase
func CreateUser() {}
// Unexported: camelCase
func validateInput() {}
Interfaces
// Use -er suffix for single-method interfaces
type Reader interface {
Read([]byte) (int, error)
}
// Use descriptive names for multi-method
type Engine interface {
Get(key []byte) ([]byte, error)
Set(key, value []byte) error
}
Error Handling
Always handle errors
// Good
result, err := doSomething()
if err != nil {
return fmt.Errorf("doing something: %w", err)
}
// Bad - ignoring error
result, _ := doSomething()
Error wrapping
// Wrap with context
if err != nil {
return fmt.Errorf("creating user %s: %w", username, err)
}
Error types
// Define package errors
var (
ErrNotFound = errors.New("not found")
ErrInvalid = errors.New("invalid input")
)
Comments
Package comments
// Package nornicdb provides a graph database with memory decay.
//
// NornicDB implements a Neo4j-compatible graph database with
// vector search and automatic memory management.
package nornicdb
Function comments
// CreateUser creates a new user with the given credentials.
// Returns ErrUserExists if the username is already taken.
func CreateUser(username, password string) (*User, error) {
Inline comments
// Use sparingly, only when needed
func complex() {
// Step 1: Validate input
if err := validate(); err != nil {
return err
}
// Step 2: Process data
// This algorithm is O(n log n) due to...
process()
}
Code Organization
File structure
- Package declaration
- Imports (stdlib, then external, then internal)
- Constants
- Package variables
- Types
- Constructor functions
- Methods
- Helper functions
Import grouping
import (
// Standard library
"context"
"fmt"
"time"
// External packages
"github.com/stretchr/testify/assert"
// Internal packages
"github.com/orneryd/nornicdb/pkg/storage"
)
Best Practices
Use context
func DoSomething(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
// continue
}
}
Avoid global state
// Bad
var globalDB *Database
// Good - pass dependencies
func NewService(db *Database) *Service {
return &Service{db: db}
}
Prefer composition
// Good
type Server struct {
db *Database
auth *Authenticator
}
// Avoid deep inheritance
Linting
Run before committing:
golangci-lint run
See Also
- Testing - Testing guidelines
- Setup - Development setup
- Contributing - Contribution process