Hardcode is the practice of placing immutable values directly in source code instead of externalizing them. According to the Stack Overflow Developer Survey 2024, over 67% of developers regularly face problems caused by hardcoded parameters. This programming technique contradicts the principles of flexible development and creates serious risks when moving an application between environments — from a local machine to a production server.
Key Takeaways
Hardcode (hard coding) is an anti-pattern where data, configuration parameters, or settings are embedded directly into the program text. Instead of reading these values from external sources, the developer writes them as literals — strings, numbers, boolean values — directly in the function body, class, or module. The term originated in the developer community in the 1980s, when software began to spread across different hardware platforms and it became obvious that hardcoded parameters hindered portability.
The main problem with hardcode is that changing any such value requires editing source code, recompilation, and redeployment of the application. This makes the update process slow, error-prone, and dangerous — the developer may accidentally change something else in the code while editing a hardcoded parameter. In modern DevOps practices, this approach is strongly discouraged.
According to Veracode State of Software Security 2024, about 23% of all vulnerabilities in commercial applications are related to hardcoded credentials. This makes fighting hardcode not only a matter of convenience but also a critical information security task.
A hardcoded value is any number, string, or setting that is written directly in code rather than loaded from configuration. For example, if a developer writes `connectionTimeout = 30` inside a database connection class — that is hardcode. If they read the timeout from an environment variable or configuration file — that is the correct approach.
The word hardcode comes from the English term hard code — meaning “rigid code.” In Russian-speaking communities, variations like “sew in,” “hardcode,” and “rigidly write” are also used. Unlike flexible configurations, hardcode is literally “sewn into” the executable file and cannot be changed without rebuilding.
Hardcode creates many problems in the long term. The first and most obvious is the inability to change application behavior without modifying source code. The second is the risk of leaking confidential information. The third is the complication of testing, especially unit and integration testing.
In Agile and DevOps, where rapid deployment across different environments — development, staging, production — is required, hardcode becomes an insurmountable obstacle. The team has to edit code before each deployment or use manual patches, which contradicts the principles of Continuous Delivery.
A Cambridge University study (2023) showed that projects with high levels of hardcode have 47% more defects at release and require 2.3 times more time to make changes. This confirms that the maintenance cost of hardcoded code significantly exceeds the time savings at the initial stage of development.
An application with hardcoded parameters is difficult to adapt to different platforms. For example, the file path `C:\Users\admin\data.txt` will not work on a Linux server. And a font size of 14pt may look different on devices with different pixel densities.
When hardcode is scattered throughout a project, the developer has to search for each value manually using grep or IDE search. This slows down development, increases the chance of missing a needed value, and opens the door to bugs. Meanwhile, a new team member spends significantly more time understanding “magic numbers” and strings.
Passwords and credentials are the most dangerous type of hardcode. Developers often save database passwords, third-party API keys, and authorization tokens directly in code for convenience during local development but forget to externalize them before committing. This leads to leaks in public repositories.
URLs and endpoints of external services also often fall victim to hardcode. When changing hosting or API version, the developer has to update URLs in dozens of places. If the address is hardcoded in multiple modules, some links remain old, and the application works incorrectly.
Magic numbers — numeric constants without explanation. For example, `price * 0.85` instead of `price * DISCOUNT_RATE`. The code reader does not understand what 0.85 means. This is a classic example of hardcode, described by Martin Fowler in his book “Refactoring” (1999).
| Type of Hardcode | Example | Correct Approach |
|---|---|---|
| Credentials | `password = “qwerty123”` | Environment variable |
| Server URL | `url = “https://old-server.com/api”` | Configuration file |
| Timeouts | `setTimeout(5000)` | Configuration parameter |
| UI Sizes | `width = 320` | Responsive calculation |
| File Paths | `“./data/output.txt”` | Command line argument |
String literals repeated in different parts of a program are another common type of hardcode. For example, dictionary keys, HTTP headers, view names in an iOS application. If a string changes in one place but remains in another, the application breaks. The solution is to externalize strings into constants or localization files.
Application modes (debug/release), logging settings, SMTP server addresses — all these parameters should be external. If they are hardcoded, when moving to another server the application may fail to start or behave unpredictably.
Hardcoded passwords and keys pose a direct threat to application security. If an attacker gains access to the source code (through repository leaks, insider threats, or decompilation), they instantly gain access to all protected resources. In 2023, GitHub discovered over 12 million secret leaks in public repositories.
The OWASP (Open Web Application Security Project) standard includes hardcoded credentials in category A04:2021 — Insecure Design. OWASP recommends never storing passwords, tokens, or keys in source code. Instead, use specialized secret management services: HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault.
A security audit conducted by Positive Technologies (2024) showed that 78% of tested mobile applications contain at least one hardcoded key or token. For web applications, this figure is 62%. Most vulnerabilities can be eliminated by simply externalizing data into configuration files.
# hardcoded secrets — unsafe
password = "supersecret123"
api_key = "sk-abc123def456"
# safe approach — read from env vars
import os
password = os.getenv("DB_PASSWORD")
api_key = os.getenv("API_KEY")
Git preserves the entire commit history. If a hardcoded password ends up in a repository, it remains in history even after deletion from the current version. Tools like git-secrets and truffleHog help detect such leaks, but it is better to prevent them at the code review stage.
Standards such as PCI DSS, GDPR, and HIPAA directly prohibit storing confidential data in source code. Using hardcode can lead to legal consequences and fines, especially in the financial and healthcare sectors.
The first step toward eliminating hardcode is awareness at the team level. Code review should include checks for hardcoded values. Set up a linter or static analyzer that will highlight potential hardcode. For TypeScript, ESLint with the no-hardcoded-credentials rule works well; for Python, Bandit.
The second step is implementing the Configuration as Code pattern. All parameters that may differ across environments should be stored in environment variables or configuration files. Libraries like dotenv (Node.js), python-decouple (Python), or Spring Cloud Config (Java) make this approach standard.
The third step is using configuration management services: Consul, etcd, Zookeeper. For cloud projects, AWS Parameter Store, Google Cloud Secret Manager, or Azure App Configuration are suitable. In a microservice architecture, centralized configuration management is critical.
Document each configuration parameter: its purpose, allowed values, default value. Use schema validation for configuration — this allows catching errors at application startup. Create an .env.example file with all required variables but without real values.
Let us consider a concrete example in JavaScript. Before refactoring, the code contains a hardcoded URL and timeout. After refactoring, all parameters are externalized to configuration. This makes the code testable, flexible, and secure.
// before refactoring — hardcoded values
const response = await fetch("https://api.example.com/v1/users", {
timeout: 5000,
headers: { "Authorization": "Bearer sk-abc" }
});
// after refactoring — config driven
const config = {
apiUrl: process.env.API_URL,
timeout: parseInt(process.env.API_TIMEOUT || "30000"),
authToken: process.env.AUTH_TOKEN
};
const response = await fetch(config.apiUrl, {
timeout: config.timeout,
headers: { "Authorization": "Bearer " + config.authToken }
});
In Java, hardcode often appears as database connection strings. Using Spring Boot with application.yml solves this problem: the file contains profiles for different environments, and the code reads values through the @Value annotation.
// hardcoded — Java example
class DatabaseConnection {
private String url = "jdbc:mysql://localhost:3306/mydb";
private String user = "admin";
private String password = "pass123";
}
// proper config via Spring Boot
@Value("${db.url}")
private String url;
Approaches to fighting hardcode depend on the language and ecosystem. In interpreted languages (Python, JavaScript, Ruby), configuration is usually stored in environment variables or .env files. In compiled languages (Java, C#, Go), it is stored in YAML, JSON, XML configuration files or embedded resources.
In Python, the python-decouple library is popular — it reads configuration from .env files and provides typed getters. In Go, Viper is used — a powerful library for working with configurations from different sources. In Swift for iOS development, configurations are externalized to Info.plist or separate Configuration files.
Static analysis tools such as SonarQube, ESLint, Pylint can automatically detect hardcoded values. SonarQube has built-in rules for finding magic numbers and strings in code across different languages. Setting up such checks in a CI/CD pipeline is the best way to prevent new hardcode from appearing.
| Language | Configuration Method | Popular Library |
|---|---|---|
| JavaScript | .env + environment variables | dotenv |
| Python | .env + environment | python-decouple |
| Java | application.yml/properties | Spring Cloud Config |
| Go | config.yaml + env | Viper |
| Swift | Configuration.xcconfig | Build Configuration |
Pre-commit Git hooks can run scripts that check commits for hardcoded secrets. The git-secrets tool scans commits for matches against regular expressions for passwords, keys, and tokens. TruffleHog and Gitleaks go further — they check the entire git history for leaks.
Frequently Asked Questions
A variable stores a value that can change during program execution. Hardcode is a literal written directly in the function or class body that is not meant to change without editing the source code. For example, `let port = 8080` inside a method is hardcode, while `let port = config.port` is the correct use of a variable.
In the vast majority of cases — yes. However, there are exceptions: values that are guaranteed not to change over the entire lifetime of the application. For example, mathematical constants (π = 3.14159) or physical constants. But even these are better defined as named constants so it is clear what the number means.
Use a static code analyzer: SonarQube, ESLint with no-magic-numbers rules, Pylint with const-naming-style. For searching secrets — git-secrets, truffleHog or Gitleaks. Regular expressions to search for: passwords after `password =`, URLs with http/https, numeric constants without explicit names. Manual audit through grep or IDE search also helps.
Magic numbers are numeric literals in code without explanation of their meaning. For example, `if (age > 18)` — the number 18 is understandable, but `if (score > 0.85)` — it is not. The danger is that when changing such a number, the developer may miss one of the places where it is used. As a result, the program logic breaks and the bug is hard to track down.
No, excessive configurability complicates the code. The golden rule: externalize what may change when the environment or requirements change. Internal constants that do not change for years (for example, standard HTTP method names) can remain in code. Follow the YAGNI principle — do not add configuration “just in case.”
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also