A powerful, easy-to-use Node.js framework that gives you everything you need to build web applications quickly. Think of it as your Swiss Army knife for web development - it includes a web server, database, file operations, caching, and much more, all in one package.
- Zero Configuration: Get started in seconds, not hours
- Everything Included: Web server, database, file operations, caching, and more
- Natural Language: Use human-friendly syntax for dates, times, and cron jobs
- Production Ready: Built-in security features and comprehensive testing
- Beginner Friendly: Simple examples that anyone can understand
- π Full Web Server (ExpressJS) - Handle HTTP requests and responses
- π HTTP Client (Axios) - Make API calls to other services
- πΎ In-Memory Caching - Store data temporarily for faster access
- ποΈ SQL-Like Database - Store and query data without complex setup
- π UUID Generator - Create unique identifiers for your data
- π Smart Date Parsing - Use natural language like "next friday"
- β° Timestamps - Easy time formatting and timezone handling
- π File Operations - Read, write, append, and manage files
- β²οΈ Cron Jobs - Schedule tasks with natural language
- π₯οΈ Shell Commands - Run system commands from Node.js
npm install @fwd/serverLet's build a simple web application that greets visitors:
const server = require('@fwd/server')
// Create a route that responds to GET requests to the homepage
server.get('/', (req, res) => {
res.send("Hello, World! Welcome to my website!")
})
// Start the server on port 8080
server.start(8080)That's it! Your web server is now running at http://localhost:8080. When someone visits your site, they'll see "Hello, World! Welcome to my website!"
π‘ Tip: Static files (like CSS, images, JavaScript) are automatically served from the
/publicfolder. You can change this withserver.start(8080, { publicFolder: '/dist' }).
Let's build a complete user registration system:
const server = require('@fwd/server')
// Serve the registration form
server.get('/register', (req, res) => {
res.send(`
<form method="POST" action="/register">
<h2>Create Your Account</h2>
<input type="text" name="name" placeholder="Your Name" required>
<input type="email" name="email" placeholder="Your Email" required>
<button type="submit">Register</button>
</form>
`)
})
// Handle the registration form submission
server.post('/register', async (req, res) => {
const { name, email } = req.body
// Validate email format
if (!server.isEmail(email)) {
return res.send("Please enter a valid email address!")
}
// Create a new user in the database
const user = await server.database.create('users', {
id: server.uuid(), // Generate unique ID
name: name,
email: email,
created_at: server.timestamp() // Current timestamp
})
res.send(`Welcome ${name}! Your account has been created.`)
})
// View all registered users
server.get('/users', async (req, res) => {
const users = await server.database.get('users')
res.send({ users: users })
})
server.start(8080)Create a simple blog that stores posts in files:
const server = require('@fwd/server')
// Display all blog posts
server.get('/', async (req, res) => {
const posts = await server.list('./posts')
let html = '<h1>My Blog</h1>'
for (const post of posts) {
const content = await server.read(`./posts/${post}`)
html += `<div><h3>${post.replace('.txt', '')}</h3><p>${content}</p></div>`
}
html += '<a href="/new">Write New Post</a>'
res.send(html)
})
// Show form to create new post
server.get('/new', (req, res) => {
res.send(`
<form method="POST" action="/new">
<h2>Write New Post</h2>
<input type="text" name="title" placeholder="Post Title" required>
<textarea name="content" placeholder="Post Content" required></textarea>
<button type="submit">Publish Post</button>
</form>
`)
})
// Save new blog post
server.post('/new', async (req, res) => {
const { title, content } = req.body
// Create filename from title (replace spaces with dashes)
const filename = title.toLowerCase().replace(/\s+/g, '-') + '.txt'
// Save post to file
await server.write(`./posts/${filename}`, content)
res.send(`Post "${title}" has been published! <a href="/">View all posts</a>`)
})
server.start(8080)Build an app that fetches data from external APIs:
const server = require('@fwd/server')
// Get random joke from external API
server.get('/joke', async (req, res) => {
try {
const response = await server.http.get('https://api.chucknorris.io/jokes/random')
const joke = response.data
res.send(`
<h2>Random Chuck Norris Joke</h2>
<p>${joke.value}</p>
<a href="/joke">Get Another Joke</a>
`)
} catch (error) {
res.send("Sorry, couldn't fetch a joke right now.")
}
})
// Weather information (example with caching)
server.get('/weather/:city', async (req, res) => {
const city = req.params.city
// Check if we have cached weather data
let weather = server.cache(`weather_${city}`)
if (!weather) {
// Fetch fresh data from API
try {
const response = await server.http.get(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`)
weather = response.data
// Cache for 10 minutes (600 seconds)
server.cache(`weather_${city}`, weather, 600)
} catch (error) {
return res.send(`Could not fetch weather for ${city}`)
}
}
res.send(`
<h2>Weather in ${city}</h2>
<p>Temperature: ${weather.main.temp}Β°F</p>
<p>Description: ${weather.weather[0].description}</p>
`)
})
server.start(8080)The built-in database works like a simple JSON database - perfect for prototypes and small applications:
const server = require('@fwd/server')
// Create a new record
const user = await server.database.create('users', {
name: 'John Doe',
email: 'john@example.com',
age: 30
})
// Find all users
const allUsers = await server.database.get('users')
// Find users with specific criteria
const youngUsers = await server.database.find('users', { age: { $lt: 25 } })
// Find one specific user
const john = await server.database.findOne('users', { name: 'John Doe' })
// Update a user
await server.database.update('users', john.id, { age: 31 })
// Delete a user
await server.database.remove('users', john.id)Handle files easily with built-in methods:
const server = require('@fwd/server')
// Read a file
const content = await server.read('./data.txt')
console.log(content)
// Write to a file
await server.write('./output.txt', 'Hello, World!')
// Append to a file
await server.append('./log.txt', 'New log entry\n')
// Prepend to a file (add content at the beginning)
await server.prepend('./notes.txt', 'Important: ')
// Copy a file
await server.copy('./source.txt', './backup.txt')
// Delete a file
await server.unlink('./old-file.txt')
// List files in a directory
const files = await server.list('./documents')
console.log(files) // ['file1.txt', 'file2.txt', 'folder1']Work with dates using natural language:
const server = require('@fwd/server')
// Natural language date parsing
console.log(server.date('next friday')) // Next Friday's date
console.log(server.date('tomorrow')) // Tomorrow's date
console.log(server.date('in 3 days')) // Date 3 days from now
console.log(server.date('last monday')) // Last Monday's date
// Timestamps
console.log(server.timestamp()) // Current Unix timestamp
console.log(server.timestamp('LLLL')) // "Monday, September 28, 2020 4:30 PM"
console.log(server.timestamp('LL')) // "September 28, 2020"
console.log(server.timestamp('LLL', 'America/New_York')) // With timezone
// Time conversions
console.log(server.time(5, 'seconds')) // 5000 (milliseconds)
console.log(server.time(1, 'hour')) // 3600000 (milliseconds)
console.log(server.time(2, 'days')) // 172800000 (milliseconds)Schedule tasks using natural language:
const server = require('@fwd/server')
// Run every hour
server.cron(() => {
console.log('Hourly backup completed')
}, 'every 1 hour')
// Run every 30 minutes
server.cron(() => {
console.log('Checking for updates...')
}, 'every 30 minutes')
// Run daily at midnight
server.cron(() => {
console.log('Daily cleanup started')
}, 'every 1 day')
// Run immediately and then every 5 minutes
server.cron(() => {
console.log('Health check performed')
}, 'every 5 minutes', true) // true = run immediatelyCreate unique identifiers for your data:
const server = require('@fwd/server')
// Generate a full UUID
const id = server.uuid()
console.log(id) // "9e471b08-38fe-11eb-adc1-0242ac120002"
// Generate a shorter UUID
const shortId = server.uuid(8)
console.log(shortId) // "9e471b08"
// Generate UUID with prefix
const prefixedId = server.uuid(16, 'user_')
console.log(prefixedId) // "user_9e471b08-38fe"
// Generate UUID without dashes
const cleanId = server.uuid(32, '', true)
console.log(cleanId) // "9e471b0838fe11ebadc10242ac120002"Run shell commands from your Node.js application:
const server = require('@fwd/server')
// Get system information
const cpuUsage = await server.exec('top -l 1 | grep "CPU usage"')
console.log(cpuUsage)
// List files in current directory
const files = await server.exec('ls -la')
console.log(files)
// Get disk usage
const diskUsage = await server.exec('df -h')
console.log(diskUsage)
// Execute with options
const result = await server.exec('long-running-command', {
timeout: 60000, // 60 second timeout
maxBuffer: 1024 * 1024 // 1MB buffer limit
})Store data temporarily to improve performance:
const server = require('@fwd/server')
// Store data in cache
server.cache('user_123', { name: 'John', email: 'john@example.com' })
// Retrieve from cache
const user = server.cache('user_123')
console.log(user) // { name: 'John', email: 'john@example.com' }
// Store with expiration (expires in 300 seconds = 5 minutes)
server.cache('api_data', { data: 'some data' }, 300)
// Cache will automatically expire after 5 minutesValidate user input with built-in validators:
const server = require('@fwd/server')
// Email validation
console.log(server.isEmail('user@example.com')) // true
console.log(server.isEmail('invalid-email')) // false
// Phone number validation
console.log(server.isPhone({ value: '555-123-4567' })) // true
console.log(server.isPhone({ value: '123' })) // falseConfigure your server with security and performance options:
const server = require('@fwd/server')
server.get('/', (req, res) => {
res.send('Hello, World!')
})
server.start(8080, './my-app', {
// Security settings
cors: {
origin: ['https://mywebsite.com', 'https://app.mywebsite.com'],
credentials: true
},
// File size limits
jsonLimit: '50mb',
// Timezone for timestamps
timezone: 'America/New_York',
// Static file settings
publicFolder: './public',
maxAge: '1d', // Cache static files for 1 day
// Upload settings
uploadFolder: './uploads',
// View engine
viewEngine: 'ejs',
viewsFolder: './views'
})The framework includes comprehensive testing to ensure reliability and security. All tests pass to maintain API compatibility.
# Run all tests
npm test
# Run tests in watch mode (reruns when files change)
npm run test:watch
# Run tests with coverage report
npm run test:coverageThe test suite covers:
- β File Operations - Read, write, append, prepend, delete, copy, list
- β Utility Functions - Command execution, sleep, UUID generation, time/date functions
- β Validation Functions - Email and phone number validation
- β Cron Functionality - Scheduled task execution
- β Caching - Data storage and retrieval with expiration
- β Server Setup - HTTP method registration and routing
- β Integration Tests - End-to-end functionality testing
__tests__/
βββ file-operations.test.js # File system operations
βββ utility-functions.test.js # Core utility functions
βββ validation-functions.test.js # Input validation
βββ cron-functionality.test.js # Scheduled tasks
βββ cache-functionality.test.js # Caching system
βββ server-setup.test.js # Server configuration
βββ integration.test.js # End-to-end tests
The framework includes comprehensive security measures to protect your applications:
- Input validation and sanitization
- Dangerous character filtering (
;&|$(){}[]`) - Command length limits (1000 characters)
- Execution timeouts (30 seconds default)
- Buffer size limits (1MB)
- Path normalization and validation
- Prevention of
..directory traversal attacks - Secure file operation handling
- File size limits (50MB for files, 1MB for append/prepend)
- Input type validation
- Proper error handling without information disclosure
X-Frame-Options: DENY- Prevents clickjacking attacksX-Content-Type-Options: nosniff- Prevents MIME sniffing attacksX-XSS-Protection: 1; mode=block- Enables XSS protectionStrict-Transport-Security- Enforces HTTPS connectionsContent-Security-Policy- Restricts script and style sources
- Disabled by default (requires explicit configuration)
- Configurable allowed origins
- Credentials disabled by default
- Enhanced email validation with length limits (254 characters)
- Improved phone validation with proper error handling
- UUID generation with parameter validation
- Cron job validation with interval limits (1 second minimum)
- JSON payload size limits (1GB default, configurable)
- URL-encoded data limits
- Cron interval limits to prevent resource exhaustion
- Defense in Depth - Multiple layers of security controls
- Fail Secure - Default to secure configurations
- Input Validation - Comprehensive validation at all entry points
- Error Handling - Graceful error handling without information disclosure
- Resource Limits - Protection against resource exhaustion attacks
When using this framework in production:
- Configure CORS properly - Only allow trusted origins
- Set appropriate file size limits - Based on your application needs
- Use HTTPS - Enable SSL/TLS for secure communications
- Validate all inputs - Use the built-in validators and add custom validation
- Monitor logs - Keep an eye on error logs for suspicious activity
- Regular updates - Keep dependencies updated for security patches
We welcome contributions! Here's how you can help:
- Report Issues - Found a bug? Let us know!
- Suggest Features - Have an idea? We'd love to hear it!
- Submit Pull Requests - Fix bugs or add features
- Improve Documentation - Help others learn
# Clone the repository
git clone https://github.com/fwd/server.git
# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watchMIT License - feel free to use this in your projects!
Copyright Β© @nano2dev.
Give a βοΈ if this project helped you! It motivates us to keep improving.
Ready to build something amazing? Start with the Quick Start example above and let your creativity flow! π
