Strip the LocalStack monorepo of all AWS service provider implementations, leaving a clean, deployable core framework that:
- Receives, parses, and dispatches AWS API requests via the existing protocol stack
- Exposes a functioning plugin/extension system so service implementations can be loaded externally
- Retains the full lifecycle management runtime (ASF), persistence infrastructure, telemetry pipeline, packaging framework, and HTTP gateway
- Produces a minimal, dependency-lean Python package and Docker image that third-party or downstream service plugins can extend
The resulting codebase is a framework skeleton, not a working AWS emulator. No service endpoints should respond with business logic by default; the framework should start cleanly, log that no providers are registered, and return a structured 501 for any AWS API call that hits an unregistered service.
| Area | Path | Rationale |
|---|---|---|
| AWS protocol gateway | localstack/aws/app.py, chain.py, handlers/, protocol/, serving/, skeleton.py, spec.py, forwarder.py |
Core request parsing and dispatch; service-agnostic |
| AWS API specs | localstack/aws/api/ |
Needed by the protocol layer to parse/validate any AWS request; generated files, not service logic |
| AWS client utilities | localstack/aws/connect.py, client.py, accounts.py, scaffold.py |
Internal client factory, boto3 patching, account management |
| Service plugin system | localstack/services/plugins.py |
Plugin registry and loader; the mechanism by which services attach — keep the chassis, remove the passengers |
| Provider registry | localstack/services/providers.py |
Factory function registry; all current service entries are removed but the module is retained as the canonical place for new providers to register themselves |
| Moto service adapter | localstack/services/moto.py |
Wraps moto backends as LocalStack providers; essential scaffolding for quickly adding a new moto-backed service without writing a full provider |
| Service state helpers | localstack/services/stores.py |
Common state patterns (AccountRegionBundle, BackendDict, CrossAccountAttribute) used by any service provider; must be available for new providers to import |
| Edge router | localstack/services/edge.py |
Routes inbound traffic to service handlers |
| Internal service utilities | localstack/services/internal.py |
Framework-level internal APIs (health, ready, info endpoints) |
| Service package installers | localstack/packages/java.py, ffmpeg.py, debugpy.py |
Binary dependency installers for common service patterns (Java-based services, media processing, debug mode); kept so new service providers can declare these as package dependencies without reimplementing the installers |
| ASF runtime | localstack/runtime/ (all files) |
Lifecycle: startup, shutdown, init scripts, hook system, event bus |
| HTTP layer | localstack/http/ (all files) |
ASGI/WSGI serving, tracing, routing |
| State & persistence | localstack/state/ (all files) |
StateContainer protocol, codecs, snapshot framework |
| Package management framework | localstack/packages/api.py, core.py, plugins.py |
Binary dependency installer framework; no service-specific installers |
| Configuration | localstack/config.py, constants.py, deprecations.py |
Keep framework-level variables; prune service-specific config (see §4.3) |
| Plugin root | localstack/plugins.py |
Top-level plugin entry point |
| Telemetry/analytics | localstack/utils/analytics/ |
Usage metrics pipeline |
| General utilities | localstack/utils/ (most) |
Networking, crypto, JSON, XML, HTTP, collections, etc. |
| Development utilities | localstack/dev/ (most) |
Bootstrap, Docker helpers, process runners, test utilities |
| Testing framework | localstack/testing/ |
Pytest plugin, fixtures, snapshot testing — kept for downstream consumers |
| Extension framework | localstack/extensions/ |
Public extension API |
| DNS | localstack/dns/ |
Framework-level DNS resolution |
| CLI | localstack/cli/ |
Package management CLI |
| Logging | localstack/logging/ |
Structured logging infrastructure |
| OpenAPI spec | localstack/aws/openapi.yaml, aws/spec-patches.json |
Protocol documentation |
| Docker entrypoint | bin/docker-entrypoint.sh, bin/docker-helper.sh |
Container bootstrap |
| Build system | pyproject.toml, Makefile, plux.ini (trimmed) |
Keep, prune service entries |
| Area | Path | Rationale |
|---|---|---|
| All AWS service implementations | localstack/services/<service>/ (all 39+) |
Pure service business logic |
| Service-specific utilities | localstack/utils/kinesis/, utils/cloudwatch/ |
Utilities tightly coupled to individual services with no framework consumers |
| All service tests | tests/aws/services/, tests/integration/services/ |
Service-level integration/unit tests |
| Service-specific fixtures | Service-level conftest.py files |
|
| CloudFormation templates in tests | tests/aws/templates/, tests/aws/cdk_templates/ |
Service test data |
-
No regressions to the plugin system. The
plux-based plugin API must remain fully functional so downstream service packages can register providers using the existing@aws_provider()decorator andplux.inientry-point convention without modification. -
Framework must start and serve requests. After stripping,
localstack start(or the Docker container) must reach theon_infra_readystate without errors. Unknown service calls should receive a structured 501 response, not a crash. -
Public APIs must remain stable. The following public APIs must not change signatures, locations, or semantics:
localstack.services.plugins.aws_providerlocalstack.services.plugins.Servicelocalstack.services.plugins.ServiceProviderlocalstack.services.plugins.ServicePluginManagerlocalstack.runtime.hooks.*decoratorslocalstack.state.*protocolslocalstack.extensions.api.*localstack.packages.api.*
-
No circular imports introduced. Each removal must be checked for import-graph side effects. Use
importliblazy loading where needed rather than introducing new module-level imports. -
Preserve plux entry-point namespaces. Even if a namespace becomes empty (e.g.
[localstack.aws.provider]), the section must remain inplux.iniso downstream packages can inject into it. -
Dependency minimization is secondary to correctness. Remove only dependencies that are exclusively used by service implementations and have no framework usage. When in doubt, keep the dependency and annotate it as a candidate for future removal.
-
No git history rewriting. All changes go through normal commits on a feature branch; do not squash or force-push history.
-
Tests that exercise the framework directly must continue to pass. This includes unit tests for the HTTP layer, state system, runtime lifecycle, plugin loader, and config — but excludes service-level integration tests.
localstack/services/
├── plugins.py KEEP — plugin registry chassis
├── providers.py KEEP — factory function registry; all current entries removed, module retained
├── edge.py KEEP — framework edge router
├── internal.py KEEP — health/ready/info endpoints
├── moto.py KEEP — moto adapter; scaffolding for new moto-backed providers
├── stores.py KEEP — common state patterns (AccountRegionBundle, BackendDict)
├── acm/ REMOVE
├── acm_pca/ REMOVE
├── apigateway/ REMOVE (includes resource_providers/)
├── appsync/ REMOVE
├── athena/ REMOVE
├── batch/ REMOVE
├── ce/ REMOVE
├── cloudformation/ REMOVE (includes resource_providers/ — 100+ plugins)
├── cloudfront/ REMOVE
├── cloudtrail/ REMOVE
├── cloudwatch/ REMOVE
├── codecommit/ REMOVE
├── cognito_idp/ REMOVE
├── cognito_identity/ REMOVE
├── dms/ REMOVE
├── ds/ REMOVE
├── dynamodb/ REMOVE
├── ec2/ REMOVE (includes resource_providers/)
├── ecr/ REMOVE
├── ecs/ REMOVE
├── efs/ REMOVE
├── elasticache/ REMOVE
├── emr/ REMOVE
├── es/ REMOVE
├── events/ REMOVE
├── firehose/ REMOVE
├── glue/ REMOVE
├── iam/ REMOVE
├── iot/ REMOVE
├── kafka/ REMOVE
├── kinesis/ REMOVE
├── kms/ REMOVE
├── lambda_/ REMOVE (includes runtime executor plugin)
├── logs/ REMOVE
├── mediastore/ REMOVE
├── opensearch/ REMOVE
├── rds/ REMOVE
├── redshift/ REMOVE
├── resource_groups/ REMOVE
├── route53/ REMOVE
├── route53resolver/ REMOVE
├── s3/ REMOVE
├── s3control/ REMOVE
├── scheduler/ REMOVE
├── secretsmanager/ REMOVE
├── ses/ REMOVE
├── sns/ REMOVE
├── sqs/ REMOVE
├── ssm/ REMOVE
├── stepfunctions/ REMOVE
├── transcribe/ REMOVE
├── xray/ REMOVE
└── ...any others REMOVE
| Section | Action | Notes |
|---|---|---|
[localstack.aws.provider] |
CLEAR entries, keep section | Remove all <service>:default = ... lines; section must remain for downstream packages |
[localstack.cloudformation.resource_providers] |
CLEAR entries, keep section | Remove all 100+ resource provider lines |
[localstack.lambda.runtime_executor] |
CLEAR entries, keep section | |
[localstack.packages] |
KEEP | Package installer entries are retained alongside their installer modules so new providers can declare these packages as dependencies |
[localstack.hooks.on_infra_start] |
PARTIAL | Remove service-specific hooks; keep framework hooks (analytics, DNS, etc.) |
[localstack.hooks.on_infra_shutdown] |
PARTIAL | Same as above |
[localstack.hooks.on_infra_ready] |
PARTIAL | Remove service-dependent init runners if any |
[localstack.hooks.configure] |
KEEP | Framework-level configure hooks |
[localstack.hooks.prepare_host] |
KEEP | Host preparation hooks |
[localstack.init.runner] |
KEEP | Python and shell init script runners |
[localstack.runtime.server] |
KEEP | Hypercorn and Twisted server backends |
[localstack.runtime.components] |
KEEP | AWS components registration |
[localstack.openapi.spec] |
KEEP | OpenAPI spec registration |
[localstack.utils.catalog] |
KEEP | Service catalog utilities |
Remove from runtime dependencies:
| Package | Reason for removal |
|---|---|
aws-sam-translator |
Only used by CloudFormation SAM transform |
antlr4-python3-runtime |
Only used by Step Functions ASL parser |
jpype1 |
Only used by Step Functions JSONata engine |
opensearch-py |
Only used by OpenSearch service provider |
kclpy-ext |
Only used by Kinesis consumer library |
localstack-dualstack-proxy |
Only used by S3/EC2 dual-stack endpoint handling |
Retain (framework usage confirmed):
| Package | Framework usage |
|---|---|
plux |
Plugin system |
boto3 / botocore |
Protocol layer, internal client factory, spec loading |
pydantic |
Request/response model validation |
werkzeug |
HTTP utilities used across the framework |
hypercorn |
ASGI server |
localstack-twisted |
Twisted reactor server backend |
openapi-core |
OpenAPI validation in handlers |
docker |
Container utilities in dev/ and packages/ |
jsonschema |
JSON schema validation in protocol layer |
rolo |
HTTP routing |
cryptography |
Used in utils/crypto.py |
moto-ext |
Required by services/moto.py adapter, which is retained to support new moto-backed providers |
pymongo |
Verify — if only used by a service, remove |
requests, urllib3 |
HTTP utilities |
pyyaml |
Config and spec parsing |
click |
CLI |
Dependency groups:
base-runtimegroup: prune service-specific entriesruntimegroup: prune as above; verify no service imports remaintestgroup: keep (testing framework is retained)devgroup: keeptypehintgroup: pruneboto3-stubsservice extras that have no framework usage; keepmypy_boto3_s3etc. only if referenced in framework code
Remove or stub out config variables that are exclusively service-specific. Do not remove variables that control framework behavior even if a service also consumes them.
Remove:
KINESIS_*variables (Kinesis provider config)DYNAMODB_*variables (DynamoDB-local config)LAMBDA_*variables (Lambda runtime config — all executor, network, docker settings)S3_*variables beyondS3_SKIP_SIGNATURE_VALIDATIONif the latter has framework useSQS_*provider-specific variablesOPENSEARCH_*,ELASTICSEARCH_*provider configSTEPFUNCTIONS_*provider configTRANSCRIBE_*provider configRDS_*provider config
Keep:
SERVICES— controls which plugins are loadedDEBUG,LOG_LEVEL— framework-wideDATA_DIR,TMP_FOLDER,CACHE_DIR— directory managementLOCALSTACK_HOST,GATEWAY_LISTEN,EDGE_PORT— networkingPERSISTENCE— state persistence toggleSNAPSHOT_*— snapshot systemDISABLE_EVENTS,SKIP_SSL_CERT_DOWNLOAD— framework flags- All
Directoriesclass internals
| Path | Action |
|---|---|
localstack/utils/kinesis/ |
REMOVE — exclusively used by Kinesis provider |
localstack/utils/cloudwatch/ |
REMOVE — exclusively used by CloudWatch provider |
localstack/utils/aws/ |
PARTIAL — keep AWS utility functions used by the framework (auth, arns, protocol), remove service-specific helpers |
localstack/dev/aws/ |
PARTIAL — keep framework test utilities, remove service-specific mock builders |
| File | Action |
|---|---|
localstack/packages/api.py |
KEEP |
localstack/packages/core.py |
KEEP |
localstack/packages/plugins.py |
KEEP |
localstack/packages/java.py |
KEEP — reusable installer for any Java-based service provider (DynamoDB-local, Kinesis mock, Step Functions); new providers depend on it |
localstack/packages/ffmpeg.py |
KEEP — reusable installer for media-processing service providers |
localstack/packages/debugpy.py |
KEEP — reusable debug-mode installer available to any provider |
| Path | Action |
|---|---|
tests/aws/services/ |
REMOVE |
tests/aws/templates/ |
REMOVE |
tests/aws/cdk_templates/ |
REMOVE |
tests/aws/serverless/ |
REMOVE |
tests/aws/terraform/ |
REMOVE |
tests/aws/scenario/ |
REMOVE |
tests/integration/services/ |
REMOVE |
tests/integration/aws/ |
PARTIAL — remove service tests, keep protocol/gateway tests |
tests/unit/ |
PARTIAL — remove service unit tests, keep framework unit tests |
tests/bootstrap/ |
KEEP — framework init tests |
tests/performance/ |
PARTIAL — remove service benchmarks |
tests/integration/docker_utils/ |
KEEP |
tests/integration/dns/ |
KEEP |
tests/integration/utils/ |
KEEP |
Step 0.1 — Create feature branch
git checkout -b chore/strip-service-implementations
Step 0.2 — Capture baseline metrics
- Record current: package count in
plux.ini, total line count, number of test files,pip install --dry-rundependency list - Save to
scripts/strip-baseline.txtfor comparison after each phase
Step 0.3 — Identify all cross-references
- For each service directory, run a reverse import search to identify any framework files that import from it
- Build an import dependency graph:
python -c "import localstack.services.<svc>.provider"and log any framework-level callers - Output a
scripts/cross-refs.txtreport; this list drives the order of removals to avoid breaking framework imports
Step 0.4 — Tag current HEAD
git tag pre-strip-baseline
Work service-by-service. For each service, the micro-process is:
- Delete
localstack/services/<service>/directory - Remove any import of that service in
localstack/services/providers.py - Run
python -c "import localstack.aws.app"to verify no import error - Commit:
chore(strip): remove <service> provider
Step 1.1 — Remove low-risk, lightly-coupled services first
Services with no resource providers and no external package dependencies:
acm,acm_pca,athena,batch,ce,codecommit,cognito_identity,dms,dsecr,ecs,efs,elasticache,emr,es,glue,iotkafka,mediastore,redshift,resource_groups,route53resolvertranscribe,xray
Step 1.2 — Remove medium-complexity services
Services with resource providers or moderate cross-references:
cloudfront,cloudtrail,cloudwatch,appsynccognito_idp,firehose,scheduler,ses,ssmsecretsmanager,route53,s3control
Step 1.3 — Remove core services with resource providers
Services that have extensive CloudFormation resource provider plugins:
ec2— has EC2 resource providers (VPC, subnet, security group, etc.)iam— has IAM resource providers (role, policy, user)apigateway— has API Gateway resource providerslogs,kms,rds,opensearch
Step 1.4 — Remove high-complexity services
The most interconnected services, removed last to avoid cascading errors:
kinesis— used by other services as event sourcesqs— used by SNS, Lambda event sourcessns— has publisher infrastructure with cross-service integrationsevents(EventBridge) — has cross-service targetsdynamodb— DynamoDB-local package dependencys3— S3Provider has cross-service hooks (SNS, SQS notifications)stepfunctions— antlr/jpype dependencylambda_— most complex; runtime executor plugins, Docker integration, event source mappingscloudformation— 100+ resource provider plugins; remove last
For CloudFormation specifically:
- Delete all
localstack/services/cloudformation/resource_providers/first (100+ plugin files) - Then delete the rest of
localstack/services/cloudformation/
Step 1.5 — Clear service factory functions from providers.py
After all service directories are deleted:
- Remove all
def <service>(...)factory functions fromlocalstack/services/providers.py; leave the module structure, imports, and any helper utilities intact - Do not delete
providers.py,moto.py, orstores.py— these are retained as scaffolding for new providers - Verify
localstack/services/plugins.pyandlocalstack/services/moto.pyimport cleanly in isolation
Step 2.1 — Clear [localstack.aws.provider]
- Remove all service provider entries
- Leave the section header in place with a comment:
# Service providers registered by downstream packages
Step 2.2 — Clear [localstack.cloudformation.resource_providers]
- Remove all 100+ resource provider entries
- Leave section header with comment
Step 2.3 — Clear [localstack.lambda.runtime_executor]
- Remove the Lambda runtime executor entry
- Leave section header
Step 2.4 — Retain [localstack.packages]
- Keep all package installer entries (
dynamodb-local,elasticsearch,opensearch,kinesis-mock,lambda-runtime,jpype-jsonata,vosk,ffmpeg,java) unchanged - The installer modules (
java.py,ffmpeg.py,debugpy.py) are retained so new providers can declare these as package dependencies
Step 2.5 — Audit [localstack.hooks.*] sections
- Enumerate all hook registrations; cross-reference with removed service directories
- Remove hooks whose implementing module no longer exists
- Keep all hooks whose module is in a retained path
Step 2.6 — Validate plux.ini
python -c "import plux; plux.PluginManager('localstack.aws.provider').load_all()"This must succeed with zero providers loaded (not an error).
Step 3.1 — Update pyproject.toml ✅
- Removed from
runtimegroup:antlr4-python3-runtime,aws-sam-translator,jpype1,kclpy-ext,opensearch-py,pymongo,apispec,crontab,responses,jsonpath-ng localstack-dualstack-proxywas not present inpyproject.toml— nothing to removeairspeed-extremoved in Phase 5.3 (its sole consumertemplating.pywas deleted)- Stale
package-dataglobs,ruffexclude paths,deptryexclude paths, andDEP001ignore entries cleaned up
Step 3.2 — Update requirements files ✅
requirements-runtime.txtmanually updated to remove direct-dependency attributions for all removed packages; transitive deps still present viamoto-extretained with updated attribution comments
Step 3.3 — Retain service package installers ✅
packages/java.py,ffmpeg.py,debugpy.pyverified to compile cleanly
Step 3.4 — Verify installation ✅
pip install -e ".[runtime]" --dry-runresolves cleanly with no errors
Step 4.1 — Audit config.py for service-specific variables ✅
- Removed all
LAMBDA_*,KINESIS_*,DYNAMODB_*,SQS_*,OPENSEARCH_*,SNS_*,APIGW_*,CFN_*(exceptCFN_VERBOSE_ERRORS),SFN_*,DDB_STREAMS_PROVIDER_V2,SNS_PROVIDER_V2,TF_COMPAT_MODE,WINDOWS_DOCKER_MOUNT_PREFIX,BUCKET_MARKER_LOCAL,HOSTNAME_FROM_LAMBDA,S3_SKIP_SIGNATURE_VALIDATION,S3_SKIP_KMS_KEY_VALIDATION CONFIG_ENV_VARSlist pruned to match;analytics.pyTRACKED_ENV_VAR/PRESENCE_ENV_VARlists also cleaned- Kept with framework references:
EXTERNAL_SERVICE_PORTS_START/END—utils/common.py(PortsManager),utils/bootstrap.pyCONTAINER_RUNTIME—dev/kubernetes/__main__.pyPARITY_AWS_ACCESS_KEY_ID—aws/accounts.pyMAIN_DOCKER_NETWORK—utils/container_networking.py(LAMBDA_DOCKER_NETWORK fallback removed)DISABLE_CUSTOM_CORS_S3,DISABLE_CUSTOM_CORS_APIGATEWAY—aws/handlers/cors.pyS3_VIRTUAL_HOSTNAME,S3_STATIC_WEBSITE_HOSTNAME—utils/aws/aws_stack.py(retained —aws_stack.pykept in Phase 5.3)CFN_VERBOSE_ERRORS—testing/pytest/fixtures.py(Phase 6 target)
Step 4.2 — Audit constants.py ✅
- Removed:
LOCALSTACK_MAVEN_VERSION,ARTIFACTS_REPO,HUGGING_FACE_ENDPOINT,AWS_REGION_EU_WEST_1,DEFAULT_BUCKET_MARKER_LOCAL,LEGACY_DEFAULT_BUCKET_MARKER_LOCAL,TAG_KEY_CUSTOM_ID - All other constants have retained-code references and were kept
Step 4.3 — Audit deprecations.py ✅ — No changes needed
- No imports from
config.py; all env var names are plain strings read viaos.environ - None of the removed config variables appeared in
DEPRECATIONS(they were active options, not deprecated ones) - Existing entries for legacy deprecated variables (
KINESIS_PROVIDER,LAMBDA_EXECUTOR, etc.) kept — still useful for users with stale env vars
Step 5.1 — Remove localstack/utils/kinesis/ ✅
- Deleted:
__init__.py,kclipy_helper.py,kinesis_connector.py,java/logging.properties - Verified zero retained-code callers before deletion
Step 5.2 — Remove localstack/utils/cloudwatch/ ✅
- Deleted:
__init__.py,cloudwatch_util.py - Verified zero retained-code callers before deletion
Step 5.3 — Audit localstack/utils/aws/ ✅
- Deleted (zero retained callers, service-specific):
aws_responses.py,dead_letter_queue.py,message_forwarding.py,queries.py,templating.py - Kept (used by framework):
arns.py,aws_stack.py,client.py,client_types.py,request_context.py,resources.py airspeed-extdependency removed frompyproject.tomlandrequirements-runtime.txt(its sole consumertemplating.pywas deleted)S3_VIRTUAL_HOSTNAME,S3_STATIC_WEBSITE_HOSTNAMEinconfig.pyretained — used byaws_stack.py
Step 5.4 — Audit localstack/dev/ ✅ — No changes needed
- All files are framework-level developer tooling with no service-specific imports
debugger/plugins.py— usesconfig.DEVELOP,packages.debugpy(framework)run/(configurators, main, paths, watcher) — container runner using bootstrap/docker_utils frameworkkubernetes/__main__.py— k8s cluster config generator; pro env var names are plain strings, not Python imports
Skipped intentionally. Rationale:
- Tests have no impact on the deployed framework artifact
- Existing service tests serve as a useful reference and guardrail if/when services are re-implemented against this framework skeleton
- Service-specific tests will fail at collection time due to missing service imports, but that is acceptable — they are not run as part of the stripped build
Skipped intentionally. Rationale:
- This is an experiment with no shippable Docker artifact required
- LocalStack is run in host mode for the duration of the experiment
- Docker artifacts can be updated if/when the experiment produces a result worth packaging
Step 8.1 — Import validation
python -c "
import localstack.aws.app
import localstack.runtime.runtime
import localstack.services.plugins
import localstack.state.core
import localstack.packages.api
import localstack.extensions.api
print('All core imports OK')
"Step 8.2 — Framework startup test
# Start the framework
SERVICES="" localstack start --host 2>&1 | head -50
# Framework should reach 'Ready.' state with no service providers registeredStep 8.3 — Plugin system test
- Write a minimal in-memory test provider using the existing
@aws_provider()decorator - Register it via a temporary
plux.initest entry - Confirm it loads and responds to requests
Step 8.4 — Run retained unit tests
pytest tests/unit/ tests/integration/docker_utils/ tests/integration/dns/ tests/integration/utils/ tests/bootstrap/ -x -qAll tests in these directories must pass.
Step 8.5 — Dependency audit
pip install pipdeptree
pipdeptree --packages localstack-core
# Confirm no removed service packages appear in the dependency treeStep 8.6 — plux audit
python -c "
import plux
for ns in [
'localstack.aws.provider',
'localstack.cloudformation.resource_providers',
'localstack.packages',
]:
plugins = plux.PluginManager(ns).load_all()
print(f'{ns}: {len(plugins)} plugins')
"
# localstack.aws.provider should show 0 pluginsStep 8.7 — Regression: unknown service returns 501
localstack start &
sleep 10
aws --endpoint-url http://localhost:4566 s3 ls 2>&1
# Should return a structured error, not a crash or 500Step 9.1 — Dead import removal
- Run
ruff check --select F401 localstack/to find unused imports - Fix or suppress each one
- Run
mypy localstack/against the retained code to catch type errors introduced by removal
Step 9.2 — Update README.md
- Replace AWS service documentation with framework-only documentation
- Document how to register a service provider as an external plugin
- Document the retained framework components and their entry points
Step 9.3 — Update pyproject.toml metadata
- Update package description to reflect framework-only nature
- Update classifiers if needed
- Update
package_dataincludes to remove references to deleted files
Step 9.4 — Final baseline comparison
- Compare
scripts/strip-baseline.txtto current state - Report: lines removed, packages removed, plux entries removed, test files removed
Step 9.5 — Tag and PR
git tag post-strip-v1
git push origin chore/strip-service-implementations
gh pr create --title "chore: strip service implementations, retain core framework"| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Framework module imports service code at module level | High | High | Run import graph analysis in Phase 0.3; fix before removing |
config.py variable removal breaks framework hooks |
Medium | High | Grep all removed variables in retained code before deletion |
| plux entry-point namespace gaps break downstream packages | Low | High | Keep all section headers; never delete a namespace, only clear entries |
providers.py still imports removed service modules after clearing factory functions |
Medium | High | After removing each service directory, immediately grep providers.py for residual imports and clean them up |
moto.py or stores.py imports a service module that no longer exists |
Low | High | Run python -m py_compile localstack/services/moto.py and stores.py after each service removal to catch broken imports early |
| Lambda executor removal leaves dead Docker network config | Low | Low | Audit docker-entrypoint.sh and config.py for Lambda network vars |
| Step Functions antlr runtime removal causes import-time crash in retained code | Low | High | Grep antlr4 across retained modules before removing dependency |
Service-specific hooks registered in retained on_infra_start entries |
Medium | Medium | Audit each hook implementation path in Phase 2.5 |
Test fixtures that import removed services break conftest.py collection |
High | Medium | Run pytest --collect-only after each phase to catch early |
The extraction is complete when all of the following are true:
localstack startcompletes toReady.state with zero service providers registeredpytest tests/unit/ tests/integration/docker_utils/ tests/integration/dns/ tests/bootstrap/ -qexits 0python -c "import localstack.aws.app; import localstack.services.plugins"exits 0plux.PluginManager("localstack.aws.provider").load_all()returns an empty list- A test-only service plugin can be registered at runtime via
@aws_provider()and responds to requests - The Docker image builds successfully from the stripped
Dockerfile - The installed package has no dependency on
aws-sam-translator,antlr4-python3-runtime,jpype1, oropensearch-py;moto-extis intentionally retained to support the moto service adapter ruff check localstack/reports zero F401 (unused import) errors in retained code