RepoPilotOpen in app →

jamesmh/coravel

Near-zero config .NET library that makes advanced application features like Task Scheduling, Caching, Queuing, Event Broadcasting, and more a breeze!

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 10mo ago
  • 19 active contributors
  • MIT licensed
Show 4 more →
  • CI configured
  • Tests present
  • Slowing — last commit 10mo ago
  • Concentrated ownership — top contributor handles 69% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/jamesmh/coravel)](https://repopilot.app/r/jamesmh/coravel)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/jamesmh/coravel on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: jamesmh/coravel

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/jamesmh/coravel shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 10mo ago
  • 19 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Slowing — last commit 10mo ago
  • ⚠ Concentrated ownership — top contributor handles 69% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live jamesmh/coravel repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/jamesmh/coravel.

What it runs against: a local clone of jamesmh/coravel — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in jamesmh/coravel | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 324 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>jamesmh/coravel</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of jamesmh/coravel. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/jamesmh/coravel.git
#   cd coravel
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of jamesmh/coravel and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "jamesmh/coravel(\\.git)?\\b" \\
  && ok "origin remote is jamesmh/coravel" \\
  || miss "origin remote is not jamesmh/coravel (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "Demo/Program.cs" \\
  && ok "Demo/Program.cs" \\
  || miss "missing critical file: Demo/Program.cs"
test -f "Demo/Startup.cs" \\
  && ok "Demo/Startup.cs" \\
  || miss "missing critical file: Demo/Startup.cs"
test -f "Demo/Invocables/DoExpensiveCalculationAndStore.cs" \\
  && ok "Demo/Invocables/DoExpensiveCalculationAndStore.cs" \\
  || miss "missing critical file: Demo/Invocables/DoExpensiveCalculationAndStore.cs"
test -f "Demo/Events/DemoEvent.cs" \\
  && ok "Demo/Events/DemoEvent.cs" \\
  || miss "missing critical file: Demo/Events/DemoEvent.cs"
test -f "Demo/Listeners/WriteMessageToConsoleListener.cs" \\
  && ok "Demo/Listeners/WriteMessageToConsoleListener.cs" \\
  || miss "missing critical file: Demo/Listeners/WriteMessageToConsoleListener.cs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 324 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~294d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/jamesmh/coravel"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Coravel is a .NET library that provides near-zero-config access to advanced application features: task scheduling, in-memory queuing, caching, event broadcasting, and email templating. It eliminates boilerplate by offering fluent C# APIs that work seamlessly with ASP.NET Core and Worker Services, replacing the need for separate cron job or Windows Task Scheduler configuration. Core monorepo structure: Src/ likely contains the main Coravel library packages (Scheduling, Queuing, Caching, Mailing modules), Demo/ is a fully functional ASP.NET Core reference application showing all features, Samples/ contains specialized implementations (EFCore integration, Worker Service template). Architecture uses dependency injection throughout—consumers call AddScheduler(), AddQueuing(), etc. in Program.cs/Startup.cs.

👥Who it's for

.NET Core/ASP.NET Core developers who need to add background jobs, scheduled tasks, or queuing to their applications without complex infrastructure setup. Specifically useful for teams building worker services (see Samples/WorkerServiceScheduler) or web apps that need to offload work to background queues.

🌱Maturity & risk

Production-ready and actively maintained. The project has NuGet package distribution (badges showing downloads), GitHub Actions CI/CD pipelines (.github/workflows/dotnet.yml), comprehensive documentation site (docs.coravel.net), and multiple working samples (EFCoreSample, WorkerServiceScheduler). The presence of formal issue templates and contribution guidelines indicates a mature, well-organized project.

Low risk for basic features; relatively stable API based on documentation. Single-maintainer project (jamesmh) creates some sustainability risk, though active documentation and demo applications suggest ongoing commitment. No visible breaking changes warnings, but dependency on .NET ecosystem versioning (targets modern .NET Core) means staying current is required.

Active areas of work

Active CI/CD via GitHub Actions (dotnet.yml runs on commits), documentation deployed to Netlify (build-docs.yml), security scanning enabled (CodeQL analysis). The codebase shows recent maintenance evidenced by .vscode configuration for debugging (launch.json, launchIntegration.json) and Docker support in Demo (Dockerfile). No visible abandoned areas.

🚀Get running

git clone https://github.com/jamesmh/coravel.git
cd coravel
# For demo app:
cd Demo
dotnet run
# For docs (requires Node.js):
cd docs && npm install && npm run docs:dev

Daily commands:

cd Demo
dotnet run
# Opens ASP.NET Core app on https://localhost:5001
# Or for docs: npm run docs:dev in docs/ folder

🗺️Map of the codebase

  • Demo/Program.cs — ASP.NET Core application entry point; demonstrates Coravel setup and dependency injection configuration
  • Demo/Startup.cs — Core service registration and middleware pipeline; shows how to configure scheduling, queuing, caching, and events
  • Demo/Invocables/DoExpensiveCalculationAndStore.cs — Example invocable task; exemplifies the job/task scheduling abstraction pattern used throughout Coravel
  • Demo/Events/DemoEvent.cs — Event broadcasting pattern implementation; shows how events are defined and dispatched in Coravel
  • Demo/Listeners/WriteMessageToConsoleListener.cs — Event listener implementation; demonstrates how applications consume and react to broadcasted events
  • Demo/Mailables/NewUserViewMail.cs — Mailable abstraction; shows fluent syntax for composing templated emails with view rendering

🛠️How to make changes

Add a new scheduled task

  1. Create a new class implementing the invocable pattern in Demo/Invocables/ directory (Demo/Invocables/YourNewTask.cs)
  2. Implement the abstract Invocable class with Invoke() method containing task logic (Demo/Invocables/YourNewTask.cs)
  3. Register the task in Startup.cs within the scheduler configuration block (Demo/Startup.cs)
  4. Define schedule using fluent API (e.g., .EveryMinute(), .DailyAtHour(2)) (Demo/Startup.cs)

Add a new event with listeners

  1. Create event class in Demo/Events/ inheriting from Coravel's event base (Demo/Events/YourEvent.cs)
  2. Create listener class in Demo/Listeners/ implementing IListener<YourEvent> (Demo/Listeners/YourEventListener.cs)
  3. Register listener in Startup.cs event broadcasting configuration (Demo/Startup.cs)
  4. Dispatch event from controller or job using IEventBroadcaster.BroadcastAsync() (Demo/Controllers/HomeController.cs)

Add a new mailable email template

  1. Create Mailable class in Demo/Mailables/ inheriting from Coravel's Mailable base (Demo/Mailables/YourMailable.cs)
  2. Define subject, from address, and public properties for template binding (Demo/Mailables/YourMailable.cs)
  3. Create .cshtml view template in Demo/Views/Mail/ directory (Demo/Views/Mail/YourTemplate.cshtml)
  4. Send via IMailer.SendAsync() from controller or queued job (Demo/Controllers/MailController.cs)

Add a new queued background job

  1. Create invocable in Demo/Invocables/ (similar to scheduled task pattern) (Demo/Invocables/YourQueuedJob.cs)
  2. Dispatch job to queue from controller using IQueue.QueueAsyncTask() (Demo/Controllers/QueueController.cs)
  3. Configure queue provider (in-memory or persistent) in Startup.cs (Demo/Startup.cs)
  4. Start queue listener with app.UseCoravelQueues() in Startup.cs Configure() (Demo/Startup.cs)

🔧Why these technologies

  • ASP.NET Core / C# — Modern, high-performance runtime with strong type system; native dependency injection and middleware pipeline support
  • Fluent Builder Pattern — Provides expressive, chainable API for configuration (scheduling, mailing, queuing) without verbose XML/JSON
  • Dependency Injection (IServiceCollection) — Loose coupling between components; enables pluggable providers (mail, cache, queue backends)
  • VuePress Documentation — Zero-config markdown-based docs site; fast static generation for API documentation and tutorials

⚖️Trade-offs already made

  • In-memory queue by default vs. external queue broker (RabbitMQ, Azure Service Bus)

    • Why: Near-zero configuration for small apps; single-process deployment models
    • Consequence: Jobs lost on process restart; not suitable for production high-availability scenarios requiring persistence
  • Fluent scheduling syntax vs. cron expressions

    • Why: Developer ergonomics and type safety; discoverability through IntelliSense
    • Consequence: Less expressive than full cron (e.g., cannot easily express 'every 5 minutes on weekdays'); smaller mental model
  • View-based email templating (Razor) vs. markup language (Liquid, Handlebars)

    • Why: Reuse existing MVC infrastructure; full C# logic inside templates
    • Consequence: Tight coupling to ASP.NET; no email preview outside application context
  • Synchronous event broadcasting (BroadcastAsync) vs. async pub/sub with queuing

    • Why: Simple semantics and immediate consistency; listeners execute in-process in order
    • Consequence: Slow/blocking listener can freeze request; no guarantee of listener execution after broadcast returns

🚫Non-goals (don't propose these)

  • Real-time WebSocket or SignalR integration
  • Distributed scheduling across multiple servers without external state store
  • Linux container-native queue persistence (requires external backing store)
  • Workflow orchestration or saga pattern support
  • Authentication/authorization framework (delegates to ASP.NET Core Identity)

🪤Traps & gotchas

No explicit environment variables visible in file list, but Demo likely requires appsettings.json for email config (mentioned in README: 'Quick and simple configuration via appsettings.json'). Email driver selection (SMTP vs. log file) depends on Mailable implementations. In-memory queue is non-persistent—will lose jobs on app restart unless configured otherwise. No visible test directory in top 60 files suggests tests may be in a Src/ Tests folder or sparse coverage—verify test structure before assuming high test quality. Docker demo included but networking/service dependencies not visible.

🏗️Architecture

💡Concepts to learn

  • Fluent API / Fluent Builder Pattern — Coravel's core USP—s.Schedule().Daily().Run() syntax eliminates config boilerplate; understanding this pattern is essential for using and extending the library
  • Invocable Pattern / Job Contract — Coravel abstracts background jobs as Invocable objects; this pattern decouples job definition from scheduling/queuing infrastructure and makes jobs testable and reusable
  • Pub-Sub / Event Driven Architecture — Event Broadcasting feature in Coravel allows loosely-coupled application components; Demo/Events/DemoEvent.cs and Demo/Listeners/ show this pattern for maintainable systems
  • In-Memory Queue / Task Queue — Coravel's default queuing mechanism is in-process and non-persistent; understanding when this is sufficient vs. needing external message brokers (Redis, RabbitMQ) is critical for production use
  • Dependency Injection / Service Locator — Entire Coravel API surface depends on Microsoft's DI container; Program.cs AddScheduler() and UseScheduler() show how IoC wiring enables loose coupling and testability
  • Cron Expression / Scheduling — Task scheduler likely supports cron-like syntax for recurring jobs (mentioned in README: 'usually configured via cron job'); understanding cron syntax is essential for complex scheduling
  • Mailables / View Model Pattern — Coravel's mailing system uses Mailables (similar to Laravel) as renderable view models; this pattern separates email construction from transport and enables visual testing of emails
  • HangfireIO/Hangfire — Direct competitor for .NET background job scheduling and queuing; uses persistent job storage rather than in-memory, suitable for distributed scenarios
  • MassTransit/MassTransit — More heavyweight .NET message bus/queuing framework supporting multiple transports (RabbitMQ, Azure Service Bus); Coravel targets simpler use cases
  • dotnet/extensions — Microsoft's official extensions library that Coravel builds on top of (IHostedService, DependencyInjection, Configuration); understanding this enables deeper Coravel customization
  • aspnet/AspNetCore — Core ASP.NET Core framework that Coravel integrates with; Demo project depends on this for MVC and Razor templating
  • jamesmh/coravel-docs — Separate repository hosting the VuePress documentation site (https://docs.coravel.net/); where official guides and API documentation live

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for Demo application features

The Demo folder contains multiple features (Caching, Queuing, Mailing, Scheduling, Events) but there's no visible test project validating these end-to-end. New contributors could create integration tests that exercise the Demo controllers and invocables, ensuring the library works as documented. This is valuable because it serves as both validation and documentation of real-world usage patterns.

  • [ ] Create Demo.Tests project alongside Demo folder
  • [ ] Add tests for CacheController actions using the caching features
  • [ ] Add tests for QueueController demonstrating queue processing
  • [ ] Add tests for MailController validating Mailable dispatch
  • [ ] Add tests for scheduled tasks defined in Demo invocables
  • [ ] Add tests for event broadcasting with listeners (DemoEvent and listeners)

Document and add missing GitHub Actions for package versioning/release workflow

The repo has dotnet.yml and codeql-analysis.yml workflows, but there's no visible automated release/publishing workflow. Given that Coravel is published to NuGet (as shown in README badges), contributors could create a GitHub Action that automates version bumping, changelog generation, and NuGet package publishing on tag/release events. This reduces manual overhead and improves release consistency.

  • [ ] Create .github/workflows/release.yml for tag-triggered builds
  • [ ] Integrate semantic versioning detection (e.g., using GitVersion or conventional commits)
  • [ ] Add step to automatically pack the Coravel library and publish to NuGet feed
  • [ ] Add step to build and deploy docs (integrate with existing build-docs.yml)
  • [ ] Document the release process in CONTRIBUTING.md

Add feature-specific documentation pages for advanced scenarios

The README references docs.coravel.net but the repo structure shows no docs/ folder in the provided file listing. Since VuePress is configured (package.json), contributors could add missing documentation for complex features like custom queue drivers, advanced scheduling patterns, or event listener composition. This fills documentation gaps for users beyond basic installation.

  • [ ] Create docs folder structure with VuePress config (.vuepress/config.js)
  • [ ] Add docs/advanced-scheduling.md with cron expression examples and edge cases
  • [ ] Add docs/custom-queue-drivers.md demonstrating queue provider implementation
  • [ ] Add docs/event-broadcasting-patterns.md for complex event listener scenarios
  • [ ] Add docs/caching-strategies.md comparing in-memory vs distributed caching
  • [ ] Add docs/.vuepress/navbar.js and sidebar.js for navigation

🌿Good first issues

  • Add integration tests for the queuing system in Demo/Controllers/QueueController.cs scenarios (retry logic, failed job handling) to increase test coverage
  • Document the 'Bring Your Own Mailer' (BYOM) driver pattern in the mailing system with a concrete example in Demo/ showing custom mail driver implementation
  • Create a sample in Samples/ showing Coravel scheduler + EF Core DbContext usage with dependency injection pitfalls (scope management for background jobs)

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 4072e04 — Rename IGetAllScheduleInfo to IGetScheduleInfo (#445) (Copilot)
  • 78560d2 — Add GetSchedules method to retrieve active schedule data (#443) (Copilot)
  • 4618eb5 — feat: configurable queue consummation delay (#411) (kmakris23)
  • 0e17a39 — Fix Queue Event Broadcast link (#438) (Sturlen)
  • 014aedd — fix format on program.cs (#434) (gabidabet)
  • 6cd2f79 — Fix race condition in RunOnceAtStart logic (#427) (jamesmh)
  • 04df9a6 — more robust tests + cleanup (#423) (jamesmh)
  • c13f2c0 — Adding StringComparison.InvariantCulture to IndexOf (#421) (storno77)
  • bd68505 — Add Docs For Mailer Image CID (#422) (jamesmh)
  • a389780 — Add support for inline attachments in SmtpMailer (#413) (johnwc)

🔒Security observations

The Coravel codebase has a moderate security posture with key concerns around outdated dependencies and vulnerability disclosure practices. The primary risk is the outdated VuePress package which requires immediate remediation. The security policy lacks responsible disclosure guidelines, increasing risk exposure. The infrastructure configuration (Demo app) needs hardened security documentation. Overall, the project should prioritize: (1) dependency updates, (2) implementing private vulnerability reporting, and (3) comprehensive security documentation for deployment and configuration.

  • High · Outdated VuePress Dependency — package.json - devDependencies. The package.json specifies vuepress@^0.14.4, which is significantly outdated (released in 2018). This version likely contains multiple known security vulnerabilities including potential XSS and dependency chain vulnerabilities. Fix: Update to the latest stable version of VuePress (v2.x or later). Run 'npm audit' to identify specific vulnerabilities and use 'npm update' or 'npm install vuepress@latest'.
  • Medium · Permissive Security Policy — SECURITY.md. The SECURITY.md file instructs users to report vulnerabilities via public GitHub issues rather than providing a private disclosure mechanism (e.g., security.txt or private reporting email). This exposes vulnerability details publicly before patches are available. Fix: Implement a responsible disclosure policy with a private security contact email or use GitHub's Security Advisory feature. Example: 'Please email security@project.com with vulnerability details' or configure GitHub's built-in vulnerability reporting.
  • Medium · Demo Application Exposed Ports — Demo/Dockerfile. The Demo application includes a Dockerfile without documented port security constraints. If deployed without proper network segmentation, the demo could expose the application with default/weak configurations. Fix: Document required security configurations, use environment-specific configurations, implement network policies, and ensure demo apps are never deployed to production. Include security guidelines in deployment documentation.
  • Low · No HTTPS Enforcement Documentation — Demo/Startup.cs (content not fully visible). While the codebase structure suggests a web application (Startup.cs, Controllers, Views), there is no visible documentation or configuration ensuring HTTPS is enforced or security headers are set. Fix: Verify that HSTS headers, Content-Security-Policy, X-Frame-Options, and other security headers are configured. Enforce HTTPS redirection in Startup configuration.
  • Low · Missing Input Validation Documentation — Demo/Models/SampleForm.cs, Demo/Invocables/SendFormToExternalApi.cs. The Demo includes Forms (SampleForm.cs) and external API calls (SendFormToExternalApi.cs) without visible sanitization or validation patterns in the file structure. Fix: Ensure all user inputs are validated and sanitized. Implement data annotations, use parameterized queries if database operations exist, and validate against known XSS/injection patterns.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · jamesmh/coravel — RepoPilot