Static Analysis Without Execution
When you push a project to Deployxa, the platform needs to understand your code: which framework you are using, which runtime version, which environment variables are required, which start command to use. The traditional approach is to run your code (e.g., npm install && npm start) and see what happens, but this is slow and risky, because your code might have side effects (e.g., a script that deletes files, a package with a postinstall hook that runs arbitrary code). Deployxa's intelligence service takes a different approach: it inspects your repository via static analysis, without executing any of your code. Here is how it works, why it is safe, and what it can detect.
The direct answer is that the intelligence service reads your repository's files (package.json, requirements.txt, go.mod, Cargo.toml, etc.) and analyzes them to determine your framework, runtime, and configuration. It does not run npm install, it does not execute your scripts, and it does not evaluate any code. This makes the inspection safe (no side effects), fast (under 5 seconds for most repositories), and reliable (the results are deterministic). The intelligence service is the foundation of Deployxa's zero-config engine, which uses the inspection results to generate the correct build and start commands.
Why Static Analysis Is Safer Than Execution
Three reasons explain why static analysis is safer than execution. First, no side effects: when you run npm install, the package's postinstall hooks can execute arbitrary code, which might delete files, send network requests, or modify your system. Static analysis does not run any code, so there are no side effects. Second, no resource consumption: running npm install on a large repository can take minutes and consume gigabytes of disk space (for node_modules). Static analysis reads only the manifest files, which takes milliseconds and consumes minimal memory. Third, deterministic results: running code can produce different results depending on the environment (e.g., a package might install differently on different platforms). Static analysis produces deterministic results, because it reads the same files every time.
The trade-off is that static analysis cannot detect everything. For example, it cannot detect which environment variables your code actually uses at runtime, because those might be determined by dynamic logic. It can detect which environment variables your code references (by scanning for process.env. patterns), but it cannot know which ones are required vs. optional. This is why the intelligence service is conservative: it warns about potentially required environment variables but does not block deployment if they are missing.
What the Intelligence Service Detects
The intelligence service detects the following information from your repository:
1. Framework and runtime
By reading your manifest files (package.json, requirements.txt, go.mod, Cargo.toml, composer.json, etc.), the service identifies your framework (Next.js, Vite, FastAPI, Django, Fiber, Axum, Laravel, etc.) and runtime (Node.js, Python, Go, Rust, PHP, etc.). This determines the build and start commands.
2. Runtime version
By reading the engines field in package.json, the python_requires field in setup.py, or the go directive in go.mod, the service identifies the required runtime version. This ensures the container uses the correct version.
3. Start command
By reading the scripts.start field in package.json, the main field, or the entry point file (server.js, main.py, main.go, etc.), the service identifies the start command. This determines how the container runs your app.
4. Build command
By reading the scripts.build field in package.json, the build script, or the framework's default build command, the service identifies the build command. This determines how the container builds your app.
5. Output directory
By reading the framework's configuration (e.g., outDir in vite.config.ts, dist directory for Vite, .next directory for Next.js), the service identifies the output directory. This determines where the build artifacts are located.
6. Required environment variables
By scanning your source code for process.env., os.environ, os.Getenv, and similar patterns, the service identifies the environment variables your code references. It then cross-references these with known framework requirements (e.g., Prisma requires DATABASE_URL, NextAuth requires NEXTAUTH_SECRET) to identify potentially required variables.
7. Localhost URLs
By scanning your source code for localhost, 127.0.0.1, and similar patterns, the service identifies hardcoded localhost URLs that need to be rewritten. This is the input to the localhost rewriter.
8. Database dependencies
By scanning your manifest files for database drivers (e.g., pg for Node.js, psycopg2 for Python, pgx for Go), the service identifies database dependencies. This helps the pre-flight scanner warn about missing database environment variables.
9. SSL and domain configuration
By scanning your manifest files and configuration for SSL and domain settings, the service identifies custom domain requirements. This helps the platform configure SSL and routing correctly.
10. Dockerfile presence
By checking for a Dockerfile in the repository root, the service determines whether to use the zero-config engine or the custom Dockerfile. If a Dockerfile is present, the service uses it; otherwise, it generates the build configuration automatically.
Step-by-Step: How the Intelligence Service Works
Here is how the intelligence service processes a typical repository.
Step 1: Clone the repository
The service clones your repository to a temporary directory. This is a shallow clone (depth 1), which is fast and uses minimal disk space.
Step 2: Identify the manifest files
The service looks for known manifest files: package.json, requirements.txt, pyproject.toml, go.mod, Cargo.toml, composer.json, etc. If multiple manifest files are present (e.g., a monorepo with backend/requirements.txt and frontend/package.json), the service identifies multiple services.
Step 3: Parse the manifest files
The service parses each manifest file to extract the framework, runtime, version, and dependencies. For package.json, it reads the dependencies, devDependencies, scripts, and engines fields. For requirements.txt, it reads the package list. For go.mod, it reads the module path and Go version.
Step 4: Identify the framework
Based on the dependencies, the service identifies the framework. For example, if package.json includes next as a dependency, the framework is Next.js. If it includes vite, the framework is Vite. If requirements.txt includes fastapi, the framework is FastAPI.
Step 5: Determine the build and start commands
Based on the framework, the service determines the build and start commands. For Next.js, the build command is npm run build and the start command is npm start. For Vite, the build command is npm run build and the start command is npm run preview (or a static file server). For FastAPI, the build command is pip install -r requirements.txt and the start command is uvicorn main:app --host 0.0.0.0 --port $PORT.
Step 6: Scan for environment variables
The service scans your source code for process.env., os.environ, os.Getenv, and similar patterns. It extracts the variable names and cross-references them with known framework requirements.
Step 7: Scan for localhost URLs
The service scans your source code for localhost, 127.0.0.1, and similar patterns. It logs the files and lines where these patterns appear, which is the input to the localhost rewriter.
Step 8: Generate the build configuration
Based on the above information, the service generates the build configuration, which includes the build command, start command, output directory, required environment variables, and any necessary transformations (e.g., localhost rewriting, build resilience injection).
Common Pitfalls and Troubleshooting
The first pitfall is monorepo detection. If your repository has multiple manifest files (e.g., backend/package.json and frontend/package.json), the service needs to identify them as separate services. The fix is to structure your monorepo clearly (e.g., backend/ and frontend/ directories with their own manifest files), which the service can detect. The second pitfall is non-standard configurations. If your app uses a non-standard build or start command (e.g., a custom build script), the service might not detect it correctly. The fix is to specify the build and start commands in your manifest file (e.g., scripts.build and scripts.start in package.json). The third pitfall is dynamic environment variable references. If your code constructs environment variable names dynamically (e.g., process.env['API_' + service + '_URL']), the service cannot detect them. The fix is to use literal variable names, which the service can detect. The fourth pitfall is comments in manifest files. If your requirements.txt has comments that look like package names (e.g., # fastapi), the service might misinterpret them. The fix is to use standard comment syntax (e.g., # at the start of the line in requirements.txt). The fifth pitfall is large repositories. If your repository is very large (e.g., includes large data files), the clone might be slow. The fix is to use a shallow clone (which the service does by default) and to exclude large files via .gitignore.
The Security Model
The intelligence service is designed with security in mind. First, it does not execute any user code, which means there are no side effects and no risk of malicious code execution. Second, it reads only text files (manifests, source code), which means it does not access binary files or secrets. Third, it runs in an isolated container, which means even if a vulnerability were found in the parsing logic, the blast radius is limited. Fourth, it does not modify the user's repository, which means the inspection is read-only. For more on Deployxa's security model, see our article on securing agentic cloud deployments.
Advanced Static Analysis Patterns
Beyond the basics, static analysis benefits from several advanced patterns. The first is AST (Abstract Syntax Tree) parsing. Instead of regex-based scanning, AST parsing provides a structured representation of the code, which is more accurate and reliable. The fix is to use AST parsers (e.g., @babel/parser for JavaScript, tree-sitter for multiple languages) for complex analysis. The second is data flow analysis. Data flow analysis tracks how data flows through the code, which can detect security vulnerabilities (e.g., SQL injection, XSS). The fix is to use a static analysis tool that supports data flow analysis (e.g., Semgrep, CodeQL). The third is type inference. For dynamically-typed languages (e.g., JavaScript, Python), type inference can detect type errors without running the code. The fix is to use a type checker (e.g., mypy for Python, tsc for TypeScript). The fourth is dependency analysis. Static analysis can identify which dependencies are actually used (vs. declared but unused), which helps reduce the bundle size. The fix is to use a dependency analysis tool (e.g., depcheck for Node.js, pip-audit for Python). The fifth is security scanning. Static analysis can detect known vulnerabilities in dependencies (e.g., by cross-referencing with the CVE database). The fix is to use a security scanner (e.g., npm audit, safety for Python). Each of these patterns enhances the intelligence service's capabilities, making it more accurate and useful. For more on static analysis, see our articles on the auto-detection engine and the heuristic advisor.
Conclusion: Safe, Fast, Reliable Repository Inspection
The intelligence service is the foundation of Deployxa's zero-config engine. By inspecting your repository via static analysis, without executing any code, the service safely and quickly determines your framework, runtime, and configuration. This enables the zero-config engine to generate the correct build and start commands, the pre-flight scanner to warn about missing environment variables, and the localhost rewriter to fix hardcoded URLs, all without you writing a Dockerfile or configuration file.
Ready to deploy with zero configuration? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on Deployxa's engineering, see our articles on the auto-detection engine and the heuristic advisor. Learn about database connection pooling across blue/green deployments and building the Deployxa CLI in our companion articles. Explore our free developer tools to speed up your workflow.