diff --git a/configs/README.md b/configs/README.md
deleted file mode 100644
index 6d8772f4ce9e76b011ffcf38e25d3924359e3a37..0000000000000000000000000000000000000000
--- a/configs/README.md
+++ /dev/null
@@ -1,103 +0,0 @@
-Habitat-API Configuration
-==============================
-
-Habitat-API uses [Yacs configuration system](https://github.com/rbgirshick/yacs)
-with the paradigm of `your code + a YACS config for experiment E (+
-external dependencies + hardware + other nuisance terms ...) =
-reproducible experiment E`. Yacs advantages:
-- Checks for type consistency.
-- All parameters and default values are searchable in the code.
-- A parameter doesn't need to be set always as each parameter has a
-    default value.
-- Ability to freeze config to prevent unintended changes.
-
-## Config usage
-An example of how to merge default config with 2 others configs and overwrite
-one parameter that could come from the command line:
-```
-    merged_config = get_config(
-        config_paths=["configs/tasks/pointnav.yaml",
-            "configs/dataset/val.yaml"],
-        opts=["ENVIRONMENT.MAX_EPISODE_STEPS", steps_limit]
-    )
-
-```
-
-## Config structure
-Below is the structure of config used for Habitat:
-- Environment
-- Task
-    - Sensors
-    - Measurements
-- Simulator
-    - Agent
-        - Sensors
-- Dataset
-
-We use node names (e.g. `SENSORS: ['RGB_SENSOR', 'DEPTH_SENSOR']`) instead of list
-of config nodes (e.g. `SENSORS: [{TYPE = "HabitatSimDepthSensor",
-MIN_DEPTH = 0}, ...]`) to declare the Sensors attached to an Agent or Measures
-enabled for the Task . With this approach, it's still easy to overwrite a
-particular sensor parameter in yaml file without redefining the whole sensor
-config.
-
-## Extending the config
-Example of how to extend a config outside of `habtiat-api` repository.
-First, we create a config extending the default config in the code and re-use
-`habitat.get_config()`:
-```
-import habitat
-import argparse
-from typing import List, Optional, Union
-
-_C = habitat.get_config()
-_C.defrost()
-# Add new parameters to the config
-_C.TASK.EPISODE_INFO = habitat.Config()
-_C.TASK.EPISODE_INFO.TYPE = "EpisodeInfo"
-_C.TASK.EPISODE_INFO.VALUE = 5
-_C.TASK.MEASUREMENTS.append("EPISODE_INFO")
-
-# New function returning extended Habitat config that should be used instead
-# of habitat.get_config()
-def my_get_config(
-        config_paths: Optional[Union[List[str], str]] = None,
-        opts: Optional[list] = None,
-) -> habitat.Config:
-    CONFIG_FILE_SEPARATOR = ","
-    config = _C.clone()
-    if config_paths:
-        if isinstance(config_paths, str):
-            if CONFIG_FILE_SEPARATOR in config_paths:
-                config_paths = config_paths.split(CONFIG_FILE_SEPARATOR)
-            else:
-                config_paths = [config_paths]
-
-        for config_path in config_paths:
-            config.merge_from_file(config_path)
-
-    if opts:
-        config.merge_from_list(opts)
-
-    config.freeze()
-    return config
-
-def main():
-    parser = argparse.ArgumentParser()
-    parser.add_argument(
-        "--task-config",
-        type=str,
-        default="configs/tasks/pointnav.yaml,"
-                "configs/datasets/pointnav/habitat_test.yaml",
-    )
-    parser.add_argument(
-        "opts",
-        default=None,
-        nargs=argparse.REMAINDER,
-        help="Modify config options from command line",
-    )
-    args = parser.parse_args()
-    config = my_get_config(config_paths=args.task_config, opts=args.opts)
-    env = habitat.Env(config)
-
-```
diff --git a/configs/test/new_keys_test.yaml b/configs/test/new_keys_test.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..af9cbb87e778b2959cd890a34ffda218ba58584d
--- /dev/null
+++ b/configs/test/new_keys_test.yaml
@@ -0,0 +1,6 @@
+ENVIRONMENT:
+  NEW_KEY: 20
+  ITERATOR_OPTIONS:
+    MY_PARAM: "test"
+TASK:
+  MY_NEW_TASK_PARAM: test
diff --git a/habitat/config/__init__.py b/habitat/config/__init__.py
index 6734e3fc2cfeb467fbe56f92f09e5d9c9b7e6d8a..408bf75753299706465cda59b00dce7514f83f94 100644
--- a/habitat/config/__init__.py
+++ b/habitat/config/__init__.py
@@ -3,9 +3,122 @@
 # Copyright (c) Facebook, Inc. and its affiliates.
 # This source code is licensed under the MIT license found in the
 # LICENSE file in the root directory of this source tree.
+from habitat.config.default import Config, get_config
 
-from yacs.config import CfgNode as Config
+r"""Habitat-API Configuration
+==============================
 
-from habitat.config.default import get_config
+Habitat-API uses [Yacs configuration system](https://github.com/rbgirshick/yacs)
+with the paradigm of `your code + a YACS config for experiment E (+
+external dependencies + hardware + other nuisance terms ...) =
+reproducible experiment E`. Yacs advantages:
+- Checks for type consistency.
+- All parameters and default values are searchable in the code.
+- A parameter doesn't need to be set always as each parameter can have a
+    default value.
+- Ability to freeze config to prevent unintended changes.
+
+## Config usage
+An example of how to merge default config with 2 others configs and overwrite
+one parameter that could come from the command line:
+```
+    merged_config = get_config(
+        config_paths=["configs/tasks/pointnav.yaml",
+            "configs/dataset/val.yaml"],
+        opts=["ENVIRONMENT.MAX_EPISODE_STEPS", steps_limit]
+    )
+
+```
+
+## Config structure
+Below is the structure of config used for Habitat:
+- Environment
+- Task
+    - Sensors
+    - Measurements
+- Simulator
+    - Agent
+        - Sensors
+- Dataset
+
+We use node names (e.g. `SENSORS: ['RGB_SENSOR', 'DEPTH_SENSOR']`) instead of list
+of config nodes (e.g. `SENSORS: [{TYPE = "HabitatSimDepthSensor",
+MIN_DEPTH = 0}, ...]`) to declare the Sensors attached to an Agent or Measures
+enabled for the Task . With this approach, it's still easy to overwrite a
+particular sensor parameter in yaml file without redefining the whole sensor
+config.
+
+## Extending the config without defaults
+Create a YAML file and add new fields and values. Load the custom config using
+`habitat.get_config()` and defined fields will be merged in default Habitat config:
+```
+import habitat
+import argparse
+from typing import List, Optional, Union
+
+config = habitat.get_config("{path to user define yaml config}")
+env = habitat.Env(config)
+```
+
+## Extending the config with default values
+Example of how to extend a config outside of `habtiat-api` repository.
+First, we create a config extending the default config in the code and re-use
+`habitat.get_config()`:
+```
+import habitat
+import argparse
+from typing import List, Optional, Union
+
+_C = habitat.get_config()
+_C.defrost()
+# Add new parameters to the config
+_C.TASK.EPISODE_INFO = habitat.Config()
+_C.TASK.EPISODE_INFO.TYPE = "EpisodeInfo"
+_C.TASK.EPISODE_INFO.VALUE = 5
+_C.TASK.MEASUREMENTS.append("EPISODE_INFO")
+
+# New function returning extended Habitat config that should be used instead
+# of habitat.get_config()
+def my_get_config(
+        config_paths: Optional[Union[List[str], str]] = None,
+        opts: Optional[list] = None,
+) -> habitat.Config:
+    CONFIG_FILE_SEPARATOR = ","
+    config = _C.clone()
+    if config_paths:
+        if isinstance(config_paths, str):
+            if CONFIG_FILE_SEPARATOR in config_paths:
+                config_paths = config_paths.split(CONFIG_FILE_SEPARATOR)
+            else:
+                config_paths = [config_paths]
+
+        for config_path in config_paths:
+            config.merge_from_file(config_path)
+
+    if opts:
+        config.merge_from_list(opts)
+
+    config.freeze()
+    return config
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        "--task-config",
+        type=str,
+        default="configs/tasks/pointnav.yaml,"
+                "configs/datasets/pointnav/habitat_test.yaml",
+    )
+    parser.add_argument(
+        "opts",
+        default=None,
+        nargs=argparse.REMAINDER,
+        help="Modify config options from command line",
+    )
+    args = parser.parse_args()
+    config = my_get_config(config_paths=args.task_config, opts=args.opts)
+    env = habitat.Env(config)
+
+```"""
 
 __all__ = ["Config", "get_config"]
diff --git a/habitat/config/default.py b/habitat/config/default.py
index a57dd16de46d46b87cebb478cd783c3b78adb762..559e2c46670e8942da9ce92719eb47279b8a3eef 100644
--- a/habitat/config/default.py
+++ b/habitat/config/default.py
@@ -6,7 +6,17 @@
 
 from typing import List, Optional, Union
 
-from habitat.config import Config as CN  # type: ignore
+import yacs.config
+
+# from habitat.config import Config as CN # type: ignore
+
+# Default Habitat config node
+class Config(yacs.config.CfgNode):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs, new_allowed=True)
+
+
+CN = Config
 
 DEFAULT_CONFIG_DIR = "configs/"
 CONFIG_FILE_SEPARATOR = ","
diff --git a/test/test_config.py b/test/test_config.py
index a113e82e91354f6d501c103db46bfdcb73edb91f..d9d5b8a8490434c7640d34ba8613f8d97594207e 100644
--- a/test/test_config.py
+++ b/test/test_config.py
@@ -8,6 +8,7 @@ from habitat.config.default import get_config
 
 CFG_TEST = "configs/test/habitat_all_sensors_test.yaml"
 CFG_EQA = "configs/test/habitat_mp3d_eqa_test.yaml"
+CFG_NEW_KEYS = "configs/test/new_keys_test.yaml"
 MAX_TEST_STEPS_LIMIT = 3
 
 
@@ -22,6 +23,20 @@ def test_merged_configs():
     )
 
 
+def test_new_keys_merged_configs():
+    test_config = get_config(CFG_TEST)
+    new_keys_config = get_config(CFG_NEW_KEYS)
+    merged_config = get_config("{},{}".format(CFG_TEST, CFG_NEW_KEYS))
+    assert (
+        merged_config.TASK.MY_NEW_TASK_PARAM
+        == new_keys_config.TASK.MY_NEW_TASK_PARAM
+    )
+    assert (
+        merged_config.ENVIRONMENT.MAX_EPISODE_STEPS
+        == test_config.ENVIRONMENT.MAX_EPISODE_STEPS
+    )
+
+
 def test_overwrite_options():
     for steps_limit in range(MAX_TEST_STEPS_LIMIT):
         config = get_config(