diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py
index a5abe35f16..37294efe01 100644
--- a/commitizen/cz/base.py
+++ b/commitizen/cz/base.py
@@ -1,37 +1,14 @@
 from abc import ABCMeta, abstractmethod
-from typing import Callable, Dict, List, Optional, Tuple
+from typing import Callable, Dict, List, Optional
 
-from prompt_toolkit.styles import Style, merge_styles
+from prompt_toolkit.styles import Style
 
-from commitizen import git
+from commitizen import defaults, git
 from commitizen.config.base_config import BaseConfig
 from commitizen.defaults import Questions
 
 
 class BaseCommitizen(metaclass=ABCMeta):
-    bump_pattern: Optional[str] = None
-    bump_map: Optional[Dict[str, str]] = None
-    default_style_config: List[Tuple[str, str]] = [
-        ("qmark", "fg:#ff9d00 bold"),
-        ("question", "bold"),
-        ("answer", "fg:#ff9d00 bold"),
-        ("pointer", "fg:#ff9d00 bold"),
-        ("highlighted", "fg:#ff9d00 bold"),
-        ("selected", "fg:#cc5454"),
-        ("separator", "fg:#cc5454"),
-        ("instruction", ""),
-        ("text", ""),
-        ("disabled", "fg:#858585 italic"),
-    ]
-
-    # The whole subject will be parsed as message by default
-    # This allows supporting changelog for any rule system.
-    # It can be modified per rule
-    commit_parser: Optional[str] = r"(?P<message>.*)"
-    changelog_pattern: Optional[str] = r".*"
-    change_type_map: Optional[Dict[str, str]] = None
-    change_type_order: Optional[List[str]] = None
-
     # Executed per message parsed by the commitizen
     changelog_message_builder_hook: Optional[
         Callable[[Dict, git.GitCommit], Dict]
@@ -42,8 +19,28 @@ class BaseCommitizen(metaclass=ABCMeta):
 
     def __init__(self, config: BaseConfig):
         self.config = config
-        if not self.config.settings.get("style"):
-            self.config.settings.update({"style": BaseCommitizen.default_style_config})
+        self.style = Style(self.config.settings.get("style", defaults.style))
+        self.bump_pattern: Optional[str] = self.config.settings.get(
+            "bump_pattern", defaults.bump_pattern
+        )
+        self.bump_map: Optional[Dict[str, str]] = self.config.settings.get(
+            "bump_map", defaults.bump_map
+        )
+        self.change_type_order: Optional[List[str]] = self.config.settings.get(
+            "change_type_order", defaults.change_type_order
+        )
+        self.change_type_map: Optional[Dict[str, str]] = self.config.settings.get(
+            "change_type_map", defaults.change_type_map
+        )
+        self.commit_parser: Optional[str] = self.config.settings.get(
+            "commit_parser", defaults.commit_parser
+        )
+        self.changelog_pattern: Optional[str] = self.config.settings.get(
+            "changelog_pattern", defaults.changelog_pattern
+        )
+        self.version_parser = self.config.settings.get(
+            "version_parser", defaults.version_parser
+        )
 
     @abstractmethod
     def questions(self) -> Questions:
@@ -53,15 +50,6 @@ def questions(self) -> Questions:
     def message(self, answers: dict) -> str:
         """Format your git message."""
 
-    @property
-    def style(self):
-        return merge_styles(
-            [
-                Style(BaseCommitizen.default_style_config),
-                Style(self.config.settings["style"]),
-            ]
-        )
-
     def example(self) -> Optional[str]:
         """Example of the commit message."""
         raise NotImplementedError("Not Implemented yet")
diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py
index 7989a17122..d17f31c514 100644
--- a/commitizen/cz/conventional_commits/conventional_commits.py
+++ b/commitizen/cz/conventional_commits/conventional_commits.py
@@ -1,7 +1,11 @@
 import os
 import re
 
-from commitizen import defaults
+try:
+    from jinja2 import Template
+except ImportError:
+    from string import Template  # type: ignore
+
 from commitizen.cz.base import BaseCommitizen
 from commitizen.cz.utils import multiple_line_breaker, required_validator
 from commitizen.defaults import Questions
@@ -28,18 +32,6 @@ def parse_subject(text):
 
 
 class ConventionalCommitsCz(BaseCommitizen):
-    bump_pattern = defaults.bump_pattern
-    bump_map = defaults.bump_map
-    commit_parser = defaults.commit_parser
-    version_parser = defaults.version_parser
-    change_type_map = {
-        "feat": "Feat",
-        "fix": "Fix",
-        "refactor": "Refactor",
-        "perf": "Perf",
-    }
-    changelog_pattern = defaults.bump_pattern
-
     def questions(self) -> Questions:
         questions: Questions = [
             {
@@ -148,9 +140,20 @@ def questions(self) -> Questions:
                 ),
             },
         ]
-        return questions
+
+        return self.config.settings.get("questions", questions)
 
     def message(self, answers: dict) -> str:
+        custom_message = self.config.settings.get("message_template")
+        if custom_message:
+            message_template = Template(
+                str(self.config.settings.get("message_template", ""))
+            )
+            if getattr(Template, "substitute", None):
+                return message_template.substitute(**answers)  # type: ignore
+            else:
+                return message_template.render(**answers)
+
         prefix = answers["prefix"]
         scope = answers["scope"]
         subject = answers["subject"]
@@ -172,32 +175,36 @@ def message(self, answers: dict) -> str:
         return message
 
     def example(self) -> str:
-        return (
-            "fix: correct minor typos in code\n"
-            "\n"
-            "see the issue for details on the typos fixed\n"
-            "\n"
-            "closes issue #12"
+        return str(
+            self.config.settings.get(
+                "example",
+                "fix: correct minor typos in code\n"
+                "\n"
+                "see the issue for details on the typos fixed\n"
+                "\n"
+                "closes issue #12",
+            )
         )
 
     def schema(self) -> str:
-        return (
+        return self.config.settings.get(
+            "schema",
             "<type>(<scope>): <subject>\n"
             "<BLANK LINE>\n"
             "<body>\n"
             "<BLANK LINE>\n"
-            "(BREAKING CHANGE: )<footer>"
+            "(BREAKING CHANGE: )<footer>",
         )
 
     def schema_pattern(self) -> str:
         PATTERN = (
-            r"(?s)"  # To explictly make . match new line
+            r"(?s)"  # To explicitly make . match new line
             r"(build|ci|docs|feat|fix|perf|refactor|style|test|chore|revert|bump)"  # type
             r"(\(\S+\))?!?:"  # scope
             r"( [^\n\r]+)"  # subject
             r"((\n\n.*)|(\s*))?$"
         )
-        return PATTERN
+        return self.config.settings.get("schema_pattern", PATTERN)
 
     def info(self) -> str:
         dir_path = os.path.dirname(os.path.realpath(__file__))
diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py
index bd3cd3c7ee..b47af0c2ea 100644
--- a/commitizen/cz/jira/jira.py
+++ b/commitizen/cz/jira/jira.py
@@ -1,5 +1,6 @@
 import os
 
+from commitizen.config.base_config import BaseConfig
 from commitizen.cz.base import BaseCommitizen
 from commitizen.defaults import Questions
 
@@ -7,6 +8,13 @@
 
 
 class JiraSmartCz(BaseCommitizen):
+    def __init__(self, config: BaseConfig):
+        super().__init__(config)
+        self.bump_map = None
+        self.bump_pattern = None
+        self.commit_parser = r"(?P<message>.*)"
+        self.changelog_pattern = r".*"
+
     def questions(self) -> Questions:
         questions = [
             {
diff --git a/commitizen/defaults.py b/commitizen/defaults.py
index f6b6dee1c3..47d0b28e38 100644
--- a/commitizen/defaults.py
+++ b/commitizen/defaults.py
@@ -31,14 +31,23 @@ class Settings(TypedDict, total=False):
     version_files: List[str]
     tag_format: Optional[str]
     bump_message: Optional[str]
+    bump_pattern: Optional[str]
+    bump_map: Optional[Dict[str, str]]
     allow_abort: bool
     changelog_file: str
     changelog_incremental: bool
     changelog_start_rev: Optional[str]
+    changelog_pattern: Optional[str]
     update_changelog_on_bump: bool
     use_shortcuts: bool
-    style: Optional[List[Tuple[str, str]]]
+    style: List[Tuple[str, str]]
     customize: CzSettings
+    change_type_order: Optional[List[str]]
+    change_type_map: Optional[Dict[str, str]]
+    commit_parser: Optional[str]
+    schema: str
+    schema_pattern: str
+    questions: Questions
 
 
 name: str = "cz_conventional_commits"
@@ -80,8 +89,31 @@ class Settings(TypedDict, total=False):
         (r"^perf", PATCH),
     )
 )
-change_type_order = ["BREAKING CHANGE", "Feat", "Fix", "Refactor", "Perf"]
+change_type_order: Optional[List[str]] = None
+
 bump_message = "bump: version $current_version → $new_version"
 
 commit_parser = r"^(?P<change_type>feat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P<scope>[^()\r\n]*)\)|\()?(?P<breaking>!)?:\s(?P<message>.*)?"  # noqa
 version_parser = r"(?P<version>([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?(\w+)?)"
+
+change_type_map = {
+    "feat": "Feat",
+    "fix": "Fix",
+    "refactor": "Refactor",
+    "perf": "Perf",
+}
+
+changelog_pattern = bump_pattern
+
+style: List[Tuple[str, str]] = [
+    ("qmark", "fg:#ff9d00 bold"),
+    ("question", "bold"),
+    ("answer", "fg:#ff9d00 bold"),
+    ("pointer", "fg:#ff9d00 bold"),
+    ("highlighted", "fg:#ff9d00 bold"),
+    ("selected", "fg:#cc5454"),
+    ("separator", "fg:#cc5454"),
+    ("instruction", ""),
+    ("text", ""),
+    ("disabled", "fg:#858585 italic"),
+]
diff --git a/tests/test_bump_find_increment.py b/tests/test_bump_find_increment.py
index 826490a3ba..27279d7a34 100644
--- a/tests/test_bump_find_increment.py
+++ b/tests/test_bump_find_increment.py
@@ -5,6 +5,7 @@
 import pytest
 
 from commitizen import bump
+from commitizen.config.base_config import BaseConfig
 from commitizen.cz import ConventionalCommitsCz
 from commitizen.git import GitCommit
 
@@ -72,11 +73,12 @@
     ),
 )
 def test_find_increment(messages, expected_type):
+    cz = ConventionalCommitsCz(BaseConfig())
     commits = [GitCommit(rev="test", title=message) for message in messages]
     increment_type = bump.find_increment(
         commits,
-        regex=ConventionalCommitsCz.bump_pattern,
-        increments_map=ConventionalCommitsCz.bump_map,
+        regex=cz.bump_pattern,
+        increments_map=cz.bump_map,
     )
     assert increment_type == expected_type
 
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index e68a3abdcf..0af6f8484c 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -1,6 +1,7 @@
 import pytest
 
 from commitizen import changelog, defaults, git
+from commitizen.config.base_config import BaseConfig
 from commitizen.cz.conventional_commits.conventional_commits import (
     ConventionalCommitsCz,
 )
@@ -844,8 +845,9 @@ def test_order_changelog_tree_raises():
 
 
 def test_render_changelog(gitcommits, tags, changelog_content):
-    parser = ConventionalCommitsCz.commit_parser
-    changelog_pattern = ConventionalCommitsCz.bump_pattern
+    cz = ConventionalCommitsCz(BaseConfig())
+    parser = cz.commit_parser
+    changelog_pattern = cz.bump_pattern
     tree = changelog.generate_tree_from_commits(
         gitcommits, tags, parser, changelog_pattern
     )
@@ -854,9 +856,10 @@ def test_render_changelog(gitcommits, tags, changelog_content):
 
 
 def test_render_changelog_unreleased(gitcommits):
+    cz = ConventionalCommitsCz(BaseConfig())
     some_commits = gitcommits[:7]
-    parser = ConventionalCommitsCz.commit_parser
-    changelog_pattern = ConventionalCommitsCz.bump_pattern
+    parser = cz.commit_parser
+    changelog_pattern = cz.bump_pattern
     tree = changelog.generate_tree_from_commits(
         some_commits, [], parser, changelog_pattern
     )
@@ -869,9 +872,10 @@ def test_render_changelog_tag_and_unreleased(gitcommits, tags):
     single_tag = [
         tag for tag in tags if tag.rev == "56c8a8da84e42b526bcbe130bd194306f7c7e813"
     ]
+    cz = ConventionalCommitsCz(BaseConfig())
 
-    parser = ConventionalCommitsCz.commit_parser
-    changelog_pattern = ConventionalCommitsCz.bump_pattern
+    parser = cz.commit_parser
+    changelog_pattern = cz.bump_pattern
     tree = changelog.generate_tree_from_commits(
         some_commits, single_tag, parser, changelog_pattern
     )
@@ -882,10 +886,11 @@ def test_render_changelog_tag_and_unreleased(gitcommits, tags):
 
 
 def test_render_changelog_with_change_type(gitcommits, tags):
+    cz = ConventionalCommitsCz(BaseConfig())
     new_title = ":some-emoji: feature"
     change_type_map = {"feat": new_title}
-    parser = ConventionalCommitsCz.commit_parser
-    changelog_pattern = ConventionalCommitsCz.bump_pattern
+    parser = cz.commit_parser
+    changelog_pattern = cz.bump_pattern
     tree = changelog.generate_tree_from_commits(
         gitcommits, tags, parser, changelog_pattern, change_type_map=change_type_map
     )
@@ -900,8 +905,9 @@ def changelog_message_builder_hook(message: dict, commit: git.GitCommit) -> dict
         ] = f"{message['message']} [link](github.com/232323232) {commit.author} {commit.author_email}"
         return message
 
-    parser = ConventionalCommitsCz.commit_parser
-    changelog_pattern = ConventionalCommitsCz.bump_pattern
+    cz = ConventionalCommitsCz(BaseConfig())
+    parser = cz.commit_parser
+    changelog_pattern = cz.bump_pattern
     tree = changelog.generate_tree_from_commits(
         gitcommits,
         tags,