nopSolutions/nopCommerce
ASP.NET Core eCommerce software. nopCommerce is a free and open-source shopping cart.
Mixed signals — read the receipts
worst of 4 axesnon-standard license (Other)
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1d ago
- ✓8 active contributors
- ✓Other licensed
Show 4 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 50% of recent commits
- ⚠Non-standard license (Other) — review terms
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
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 "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/nopsolutions/nopcommerce)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/nopsolutions/nopcommerce on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: nopSolutions/nopCommerce
Generated by RepoPilot · 2026-05-09 · 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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/nopSolutions/nopCommerce 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
WAIT — Mixed signals — read the receipts
- Last commit 1d ago
- 8 active contributors
- Other licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 50% of recent commits
- ⚠ Non-standard license (Other) — review terms
<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 nopSolutions/nopCommerce
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/nopSolutions/nopCommerce.
What it runs against: a local clone of nopSolutions/nopCommerce — 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 nopSolutions/nopCommerce | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch develop exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of nopSolutions/nopCommerce. If you don't
# have one yet, run these first:
#
# git clone https://github.com/nopSolutions/nopCommerce.git
# cd nopCommerce
#
# 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 nopSolutions/nopCommerce and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "nopSolutions/nopCommerce(\\.git)?\\b" \\
&& ok "origin remote is nopSolutions/nopCommerce" \\
|| miss "origin remote is not nopSolutions/nopCommerce (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify develop >/dev/null 2>&1 \\
&& ok "default branch develop exists" \\
|| miss "default branch develop no longer exists"
# 4. Critical files exist
test -f "src/Libraries/Nop.Core/BaseEntity.cs" \\
&& ok "src/Libraries/Nop.Core/BaseEntity.cs" \\
|| miss "missing critical file: src/Libraries/Nop.Core/BaseEntity.cs"
test -f "src/Libraries/Nop.Core/Configuration/AppSettings.cs" \\
&& ok "src/Libraries/Nop.Core/Configuration/AppSettings.cs" \\
|| miss "missing critical file: src/Libraries/Nop.Core/Configuration/AppSettings.cs"
test -f "src/Libraries/Nop.Core/Caching/IStaticCacheManager.cs" \\
&& ok "src/Libraries/Nop.Core/Caching/IStaticCacheManager.cs" \\
|| miss "missing critical file: src/Libraries/Nop.Core/Caching/IStaticCacheManager.cs"
test -f "src/Libraries/Nop.Core/Caching/DistributedCacheManager.cs" \\
&& ok "src/Libraries/Nop.Core/Caching/DistributedCacheManager.cs" \\
|| miss "missing critical file: src/Libraries/Nop.Core/Caching/DistributedCacheManager.cs"
test -f "src/Directory.Build.props" \\
&& ok "src/Directory.Build.props" \\
|| miss "missing critical file: src/Directory.Build.props"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1d)"
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/nopSolutions/nopCommerce"
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).
⚡TL;DR
nopCommerce is a free, open-source ASP.NET Core eCommerce platform (15.2M lines of C#) that provides a complete shopping cart and online store solution. It runs on .NET 9 with SQL Server, PostgreSQL, or MySQL backends, and solves the problem of needing a self-hosted, customizable eCommerce platform without licensing costs or vendor lock-in. Monolithic ASP.NET Core architecture: src/Libraries/Nop.Core contains domain entities, caching abstraction (IStaticCacheManager, IDistributedCacheManager), and configuration (AppSettings). Plugin system in src/Plugins. Presentation layer uses MVC controllers, API endpoints, and Razor views. Multi-database support via abstraction layers. Caching is layered: MemoryCacheManager, DistributedCacheManager, PerRequestCacheManager.
👥Who it's for
ASP.NET Core developers and eCommerce business owners who need to build, deploy, or customize multi-tenant online stores on-premises or in the cloud, with full source code control and no SaaS limitations.
🌱Maturity & risk
Production-ready and highly mature: actively developed since 2008 with 3M+ downloads, 250k+ community members, and a professional core team. The repository contains comprehensive CI/CD (see .github/workflows/dotnet.yml), full Docker support (Dockerfile, docker-compose.yml variants for MySQL/PostgreSQL), and industry-standard architecture patterns.
Low risk for established projects; nopCommerce is battle-tested at scale. Risks are standard for large monoliths: upgrading between major versions (currently .NET 9) requires careful testing, plugin ecosystem compatibility can drift, and custom modifications to core files risk merge conflicts during updates. No single-maintainer risk—backed by nopSolutions organization.
Active areas of work
Currently tracking .NET 9 support with active CI workflows (dotnet.yml runs tests on push/PR). Build tooling includes ClearPluginAssemblies utility for deployment cleanup. Docker compose files suggest active container deployment work. No specific milestone visible, but the maintained global.json and Directory.Build.props indicate ongoing dependency management.
🚀Get running
Clone and restore with .NET CLI:
git clone https://github.com/nopSolutions/nopCommerce.git
cd nopCommerce/src
dotnet restore
dotnet build
For database setup, see docker-compose.yml or mysql-docker-compose.yml / postgresql-docker-compose.yml for containerized local dev.
Daily commands: After dotnet restore and build in src/:
cd Presentation/Nop.Web # or relevant presentation project
dotnet run
Or via Docker:
docker-compose up
Configures databases via AppSettings.json and runs migrations automatically on startup.
🗺️Map of the codebase
src/Libraries/Nop.Core/BaseEntity.cs— Root domain entity class that all business entities inherit from; foundational to the entire object model.src/Libraries/Nop.Core/Configuration/AppSettings.cs— Central configuration loader for the application; every feature depends on settings defined here.src/Libraries/Nop.Core/Caching/IStaticCacheManager.cs— Core caching abstraction interface; critical for performance across the entire platform given async-first design.src/Libraries/Nop.Core/Caching/DistributedCacheManager.cs— Distributed cache implementation for multi-server deployments; required for web farm support.src/Directory.Build.props— MSBuild properties file that defines build configuration, package versions, and compilation settings for all projects.Dockerfile— Container image definition; shows how nopCommerce is containerized and deployed in production.global.json— .NET SDK version specification; ensures all developers and CI/CD use the correct .NET 9 runtime.
🛠️How to make changes
Add a new Product Attribute Type
- Create a new enum value in the AttributeControlType or AttributeValueType enum (
src/Libraries/Nop.Core/Domain/Catalog/AttributeControlType.cs) - Extend ProductAttribute entity or create a mapping in ProductAttributeMapping (
src/Libraries/Nop.Core/Domain/Catalog/ProductAttributeMapping.cs) - Add cache invalidation logic in CacheKeyManager for attribute updates (
src/Libraries/Nop.Core/Caching/CacheKeyManager.cs) - Create a service interface and implementation following async patterns (IProductAttributeService) (
src/Libraries/Nop.Core/Domain/Catalog/ProductAttribute.cs)
Add a new Configuration Setting
- Define a new setting property in CatalogSettings, CommonConfig, or appropriate ISettings class (
src/Libraries/Nop.Core/Configuration/CommonConfig.cs) - Add the configuration key mapping in AppSettings.cs following the [ConfigurationPath] pattern (
src/Libraries/Nop.Core/Configuration/AppSettings.cs) - Register the settings interface in dependency injection during application startup (
src/Libraries/Nop.Core/Configuration/ISettings.cs) - Invalidate relevant caches in CacheKeyManager when the setting changes (
src/Libraries/Nop.Core/Caching/CacheKeyManager.cs)
Add a new Domain Entity with Caching
- Create entity class inheriting from BaseEntity in appropriate Domain folder (
src/Libraries/Nop.Core/BaseEntity.cs) - Define cache key constants following NopEntityCacheDefaults pattern (
src/Libraries/Nop.Core/Caching/NopEntityCacheDefaults.cs) - Add cache key generation in CacheKeyManager for Get, GetAll, and search operations (
src/Libraries/Nop.Core/Caching/CacheKeyManager.cs) - Create async service methods using IStaticCacheManager.GetAsync() with cache fallback pattern (
src/Libraries/Nop.Core/Caching/IStaticCacheManager.cs)
🔧Why these technologies
- ASP.NET Core — Cross-platform, high-performance, async-first framework with built-in DI and configuration.
- Entity Framework Core / LINQ — ORM for database abstraction; enables support for SQL Server, PostgreSQL, MySQL through providers.
- Distributed Caching (Redis implicit) — Essential for web farm deployments; decouples cache coherency from single-server memory.
- Docker & docker-compose — Enables cross-platform deployment on Windows, Linux, macOS; production-ready containerization.
- Async/await throughout — Every method is async; maximizes thread pool efficiency and scalability under load.
⚖️Trade-offs already made
-
Distributed Cache abstraction over direct Redis dependency
- Why: Allows pluggable cache providers (memory, Redis, etc.) without rewriting business logic.
- Consequence: Small performance overhead of abstraction layer; simplified testing via mocks.
-
Single BaseEntity with Id primary key for all entities
- Why: Simplifies ORM mapping, caching strategies, and service layer generics.
- Consequence: Less flexibility for composite keys or non-relational storage; all entities must have integer IDs.
-
Async-first design throughout (no sync-over-async)
- Why: Avoids deadlocks, maximizes scalability, aligns with modern async infrastructure.
- Consequence: Steeper learning curve; requires careful handling of ConfigureAwait in libraries.
-
Multi-tenant support via Store concept (implicit in domain)
- Why: Single deployment serves multiple storefronts; reduces hosting costs.
- Consequence: Added complexity in cache keys, settings, and query filters for store context.
🚫Non-goals (don't propose these)
- Real-time inventory synchronization across distributed warehouses
- Built-in payment processing (plugins integrate with Stripe, PayPal, etc.)
- GraphQL API (REST-based architecture only)
- Machine learning model training on-platform (AI features delegate to external providers)
🪤Traps & gotchas
—Database migrations run automatically on startup (no manual migration step if using EF Core)—watch for schema conflicts if modifying entity mappings. —Plugin loading is dynamic; assemblies in src/Plugins/ are copied to bin/ at runtime—clearing bin/ is a common troubleshooting step (see ClearPluginAssemblies.proj). —Multi-tenancy via database (not app-level)—each store is typically a separate database or schema. —Caching keys are strongly typed via CacheKeyManager—cache invalidation must match exactly. —docker-compose.yml defaults to MSSQL; use mysql-docker-compose.yml or postgresql-docker-compose.yml for other databases or you'll get connection errors.
🏗️Architecture
💡Concepts to learn
- Distributed Cache Abstraction (IStaticCacheManager vs DistributedCacheManager) — nopCommerce supports both in-process and distributed caching for web farm scenarios; understanding when to use each prevents cache misses in production
- Plugin Architecture with Dynamic Assembly Loading — Core feature enabling third-party extensions without core rebuilds; critical for customization without merge conflicts
- Multi-Tenancy via Database Isolation — nopCommerce supports multiple stores in one instance using separate databases/schemas; essential for SaaS and multi-brand deployments
- Repository Pattern with Entity Framework Core — Data access abstraction layer decouples business logic from EF; enables database-agnostic code and easier testing
- Async-First Architecture (all methods async) — Every service method uses async/await; enables scalability under load and prevents thread pool starvation in high-traffic scenarios
- CacheKey Type-Safety via CacheKeyManager — Strongly-typed cache keys prevent collisions and enable centralized cache invalidation logic; reduces bugs from string-based cache key mismatches
- Layered Architecture (Core/Data/Services/Presentation) — Clear separation of concerns makes the codebase maintainable at massive scale; domain logic is isolated from UI and data layers
🔗Related repos
simplcommerce/SimplCommerce— Direct alternative: ASP.NET Core eCommerce platform with similar layered architecture; study for feature parity or migration guidancevendure/vendure— GraphQL-first eCommerce headless platform in TypeScript; useful reference if nopCommerce adds headless/API-first capabilitiessaleor/saleor— Python-based open-source eCommerce with strong API design; compare REST/GraphQL API design patterns with nopCommerce Web API pluginnopSolutions/nopCommerce-Plugins— Official plugin ecosystem companion repo; essential for understanding plugin patterns and published extensionsaspnet/AspNetCore— Upstream framework dependency; track for .NET version updates and async/performance pattern changes
🪄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 comprehensive unit tests for Nop.Core caching layer (CacheKeyManager, DistributedCacheManager, MemoryCacheManager)
The caching system is critical to eCommerce performance, but there's no evidence of dedicated test coverage for src/Libraries/Nop.Core/Caching. With multiple cache implementations (Memory, Distributed, PerRequest, Synchronized), unit tests would prevent regressions in cache invalidation, key generation, and concurrent access patterns—crucial for web farms that nopCommerce explicitly supports.
- [ ] Create src/Tests/Nop.Tests/Caching/CacheKeyManagerTests.cs with tests for key generation and collision scenarios
- [ ] Create src/Tests/Nop.Tests/Caching/MemoryCacheManagerTests.cs with concurrency and expiration tests
- [ ] Create src/Tests/Nop.Tests/Caching/DistributedCacheManagerTests.cs with serialization and cache miss scenarios
- [ ] Add tests for DistributedCacheLocker and MemoryCacheLocker in separate test files
- [ ] Verify all existing cache-related code paths have at least 80% coverage
Add GitHub Actions workflow for multi-database testing (SQL Server, PostgreSQL, MySQL)
The repo includes separate docker-compose files for PostgreSQL and MySQL (src/postgresql-docker-compose.yml, src/mysql-docker-compose.yml) alongside the default SQL Server setup, but .github/workflows/dotnet.yml likely only tests against one database. Contributors need confidence their changes work across all three supported databases. A matrix workflow would catch database-specific migration, ORM, and query issues early.
- [ ] Examine .github/workflows/dotnet.yml to confirm current database coverage
- [ ] Create new workflow file .github/workflows/dotnet-multi-db.yml with matrix strategy for [sqlserver, postgresql, mysql]
- [ ] Use existing docker-compose files to spin up each database variant
- [ ] Run integration tests (schema migrations, data access layer) against each database
- [ ] Document in CONTRIBUTING.md that multi-database tests are run on PR submission
Add configuration documentation file for DistributedCacheConfig and CacheConfig with real-world examples
src/Libraries/Nop.Core/Configuration contains CacheConfig.cs, DistributedCacheConfig.cs, and DistributedCacheType.cs, but there's no dedicated guide in the repo documenting how to configure caching for different deployment scenarios (local development, web farm, Redis, SQL Server cache). This is a critical onboarding gap since the README highlights web farm support and Docker deployments. A concrete guide with config snippets would reduce contributor confusion and support requests.
- [ ] Create docs/CACHING_CONFIGURATION.md documenting DistributedCacheType enum values (Redis, SqlServer, RabbitMQ, etc.)
- [ ] Add code examples showing appsettings.json snippets for each cache type configuration
- [ ] Include section on configuring CacheConfig (duration, enabled/disabled scenarios) with examples
- [ ] Add troubleshooting section for common caching issues in distributed environments
- [ ] Reference this file in CONTRIBUTING.md and README.md under configuration section
🌿Good first issues
- Add unit tests for src/Libraries/Nop.Core/Caching/CacheKeyManager.cs—currently no dedicated test coverage visible in file structure; write tests for cache key collision handling and TTL logic
- Document the plugin manifest schema in CONTRIBUTING.md—the plugin system exists but the exact structure of plugin.json is not visible in file list; extract and document it
- Implement missing async variants in src/Libraries/Nop.Core/ComponentModel/—GenericListTypeConverter and GenericDictionaryTypeConverter are listed but likely have synchronous implementations; convert to ValueTask-based async where applicable per async-first policy
⭐Top contributors
Click to expand
Top contributors
- @skoshelev — 50 commits
- @exileDev — 31 commits
- @DmitriyKulagin — 14 commits
- @AndreiMaz — 1 commits
- @RomanovM — 1 commits
📝Recent commits
Click to expand
Recent commits
ed25924— #8120 Fixed tests (exileDev)1263719— #7859 Update to .NET 10. Reverted back Microsoft.Data.SqlClient to version 6.1.1. The previous one doesn't work with SQL (AndreiMaz)0d03150— Merge branch 'issue-8120-auto-cancel-unpaid-orders' into develop (exileDev)52196bc— #8120 Auto cancel unpaid orders (exileDev)2eb876a— Merge branch 'issue-8178-fill-customer-fields-regardless-excludeProperties' into develop (exileDev)ecfa3b8— #8178 Admin area. Fill some more customer fields regardless of excludeProperties param (exileDev)c744e7e— #8073 Minor fix (RomanovM)a8812e3— Merge branch '4.90-bug-fixes' into develop (exileDev)4c46d28— #8177 Ensure a database backup file exists before processing this file (exileDev)db61230— #8163 Delete temporary tables before re-creating them (exileDev)
🔒Security observations
- Critical · Hardcoded Database Password in docker-compose.yml —
docker-compose.yml (nopcommerce_database service). The docker-compose.yml file contains a hardcoded default password 'nopCommerce_db_password' for the MSSQL SA account. This credential is stored in plain text in version control and exposed in the configuration file, allowing unauthorized database access. Fix: Use environment variables or Docker secrets management. Replace hardcoded password with: SA_PASSWORD: ${SA_PASSWORD} and provide the password via .env file (which should be .gitignored) or use Docker secrets in production deployments. - High · Insecure Default Database Credentials —
docker-compose.yml. The MSSQL service is configured with weak default credentials that are commonly known and documented in the repository. An attacker can easily identify and access the database using these default credentials. Fix: Generate strong, unique passwords. Document password configuration in CONTRIBUTING.md or setup documentation without including actual credentials. Use secret management systems in production. - High · Missing HTTPS Configuration —
docker-compose.yml (ports configuration). The docker-compose.yml exposes port 80 (HTTP) without any indication of HTTPS/TLS configuration. This allows man-in-the-middle attacks and exposes user data in transit, particularly sensitive information like credentials and payment data. Fix: Enable HTTPS by: (1) Adding port 443 mapping, (2) Configuring TLS certificates in the ASP.NET Core application, (3) Adding HSTS headers, (4) Using reverse proxy with SSL termination (nginx/traefik), (5) Redirecting HTTP to HTTPS. - High · Overly Permissive File Permissions in Dockerfile —
Dockerfile (chmod 775 commands). The Dockerfile sets directory permissions to 775 (rwxrwxr-x) on sensitive directories including App_Data, DataProtectionKeys, and wwwroot. This allows write access to group and others, creating privilege escalation and data manipulation risks. Fix: Use restrictive permissions: Change 775 to 750 or 755 depending on requirements. App_Data and DataProtectionKeys should be 750. Ensure only the application user owns these directories. Run application with least privilege user (non-root). - High · Missing Non-Root User in Docker Runtime —
Dockerfile (runtime stage). The Dockerfile snippet for the runtime stage is incomplete, but based on common patterns, the application likely runs as root. This violates the principle of least privilege and allows container escape exploits to have full system access. Fix: Create and use a non-root user: Add 'RUN addgroup -g 1000 app && adduser -D -u 1000 -G app app' and 'USER app' before starting the application. Ensure proper ownership of application files. - Medium · No Volume Isolation in docker-compose.yml —
docker-compose.yml (volumes section). The defined volume 'nopcommerce_data' is not properly assigned to services. This can lead to data persistence issues and potential data leakage between containers or loss of data on container restart. Fix: Properly map volumes in the nopcommerce_database service: 'volumes: - nopcommerce_data:/var/opt/mssql'. Define explicit volume paths for data persistence and ensure backup strategies are in place. - Medium · No Resource Limits Defined —
docker-compose.yml (service definitions). The docker-compose.yml does not define CPU or memory limits for containers. This allows resource exhaustion attacks (DoS) or uncontrolled resource consumption that could affect the entire system. Fix: Add resource constraints: 'deploy: resources: limits: cpus: '1' memory: 1G' and reservations for each service to prevent resource exhaustion. - Medium · No Network Isolation in docker-compose.yml —
docker-compose.yml. Services are connected using the default network without explicit network configuration or segmentation, potentially allowing lateral movement between services. Fix: Define explicit networks: Create separate networks for frontend and database (db-network). Restrict nopcommerce_database to only communicate with nopcommerce_web service using network policies.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.