RepoPilotOpen in app →

nopSolutions/nopCommerce

ASP.NET Core eCommerce software. nopCommerce is a free and open-source shopping cart.

Mixed

Mixed signals — read the receipts

worst of 4 axes
Use as dependencyConcerns

non-standard license (Other)

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 1d ago
  • 8 active contributors
  • Other licensed
Show 4 more →
  • 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 ConcernsMixed 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.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/nopsolutions/nopcommerce?axis=fork)](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:

  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/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 |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>nopSolutions/nopCommerce</code></summary>
#!/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).

</details>

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

  1. Create a new enum value in the AttributeControlType or AttributeValueType enum (src/Libraries/Nop.Core/Domain/Catalog/AttributeControlType.cs)
  2. Extend ProductAttribute entity or create a mapping in ProductAttributeMapping (src/Libraries/Nop.Core/Domain/Catalog/ProductAttributeMapping.cs)
  3. Add cache invalidation logic in CacheKeyManager for attribute updates (src/Libraries/Nop.Core/Caching/CacheKeyManager.cs)
  4. Create a service interface and implementation following async patterns (IProductAttributeService) (src/Libraries/Nop.Core/Domain/Catalog/ProductAttribute.cs)

Add a new Configuration Setting

  1. Define a new setting property in CatalogSettings, CommonConfig, or appropriate ISettings class (src/Libraries/Nop.Core/Configuration/CommonConfig.cs)
  2. Add the configuration key mapping in AppSettings.cs following the [ConfigurationPath] pattern (src/Libraries/Nop.Core/Configuration/AppSettings.cs)
  3. Register the settings interface in dependency injection during application startup (src/Libraries/Nop.Core/Configuration/ISettings.cs)
  4. Invalidate relevant caches in CacheKeyManager when the setting changes (src/Libraries/Nop.Core/Caching/CacheKeyManager.cs)

Add a new Domain Entity with Caching

  1. Create entity class inheriting from BaseEntity in appropriate Domain folder (src/Libraries/Nop.Core/BaseEntity.cs)
  2. Define cache key constants following NopEntityCacheDefaults pattern (src/Libraries/Nop.Core/Caching/NopEntityCacheDefaults.cs)
  3. Add cache key generation in CacheKeyManager for Get, GetAll, and search operations (src/Libraries/Nop.Core/Caching/CacheKeyManager.cs)
  4. 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

  • simplcommerce/SimplCommerce — Direct alternative: ASP.NET Core eCommerce platform with similar layered architecture; study for feature parity or migration guidance
  • vendure/vendure — GraphQL-first eCommerce headless platform in TypeScript; useful reference if nopCommerce adds headless/API-first capabilities
  • saleor/saleor — Python-based open-source eCommerce with strong API design; compare REST/GraphQL API design patterns with nopCommerce Web API plugin
  • nopSolutions/nopCommerce-Plugins — Official plugin ecosystem companion repo; essential for understanding plugin patterns and published extensions
  • aspnet/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

📝Recent commits

Click to expand
  • 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.


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

Mixed signals · nopSolutions/nopCommerce — RepoPilot