diff --git a/semantic_router/__init__.py b/semantic_router/__init__.py
index b2c0b88527d68d3a0d1fc54ceea003ee44a1d88a..4e65f0023f57011e5de3f88ede6da0c002c6cb77 100644
--- a/semantic_router/__init__.py
+++ b/semantic_router/__init__.py
@@ -1,6 +1,6 @@
-from semantic_router.routers import RouterConfig, RouteLayer, HybridRouter
+from semantic_router.routers import RouterConfig, SemanticRouter, HybridRouter
 from semantic_router.route import Route
 
-__all__ = ["RouteLayer", "HybridRouter", "Route", "RouterConfig"]
+__all__ = ["SemanticRouter", "HybridRouter", "Route", "RouterConfig"]
 
 __version__ = "0.1.0.dev2"
diff --git a/semantic_router/index/__init__.py b/semantic_router/index/__init__.py
index 3a43abe936a929cf9811d0b8d6a47b6cbf3af34d..4e566d51bb28f480cef5fb6b905d28770030c6fc 100644
--- a/semantic_router/index/__init__.py
+++ b/semantic_router/index/__init__.py
@@ -1,5 +1,6 @@
 from semantic_router.index.base import BaseIndex
 from semantic_router.index.hybrid_local import HybridLocalIndex
+from semantic_router.index.hybrid_local_opt import HybridLocalOptIndex
 from semantic_router.index.local import LocalIndex
 from semantic_router.index.pinecone import PineconeIndex
 from semantic_router.index.qdrant import QdrantIndex
@@ -7,6 +8,7 @@ from semantic_router.index.qdrant import QdrantIndex
 __all__ = [
     "BaseIndex",
     "HybridLocalIndex",
+    "HybridLocalOptIndex",
     "LocalIndex",
     "QdrantIndex",
     "PineconeIndex",
diff --git a/semantic_router/routers/__init__.py b/semantic_router/routers/__init__.py
index 4ba619d5e023b420f4d96881e82866e65887fb4a..79987406ed8c430993f714f433e6df892b53e299 100644
--- a/semantic_router/routers/__init__.py
+++ b/semantic_router/routers/__init__.py
@@ -1,10 +1,10 @@
 from semantic_router.routers.base import BaseRouter, RouterConfig
-from semantic_router.routers.semantic import RouteLayer
+from semantic_router.routers.semantic import SemanticRouter
 from semantic_router.routers.hybrid import HybridRouter
 
 __all__ = [
     "BaseRouter",
     "RouterConfig",
-    "RouteLayer",
+    "SemanticRouter",
     "HybridRouter",
 ]
diff --git a/semantic_router/routers/base.py b/semantic_router/routers/base.py
index 69753e035846f9707dbc0ecfb809efa6cc254d0f..f917005199c816bd37a4135df6252259b868dc2c 100644
--- a/semantic_router/routers/base.py
+++ b/semantic_router/routers/base.py
@@ -566,9 +566,9 @@ class BaseRouter(BaseModel):
         self._write_hash()
 
     def _local_upsert(self, utterances: List[Utterance]):
-        """Adds new routes to the RouteLayer.
+        """Adds new routes to the SemanticRouter.
 
-        :param utterances: The utterances to add to the local RouteLayer.
+        :param utterances: The utterances to add to the local SemanticRouter.
         :type utterances: List[Utterance]
         """
         new_routes = {route.name: route for route in self.routes}
@@ -590,9 +590,9 @@ class BaseRouter(BaseModel):
         self.routes = list(new_routes.values())
 
     def _local_delete(self, utterances: List[Utterance]):
-        """Deletes routes from the local RouteLayer.
+        """Deletes routes from the local SemanticRouter.
 
-        :param utterances: The utterances to delete from the local RouteLayer.
+        :param utterances: The utterances to delete from the local SemanticRouter.
         :type utterances: List[Utterance]
         """
         # create dictionary of route names to utterances
@@ -704,7 +704,7 @@ class BaseRouter(BaseModel):
         return cls(encoder=encoder, routes=config.routes, index=index)
 
     def add(self, route: Route):
-        """Add a route to the local RouteLayer and index.
+        """Add a route to the local SemanticRouter and index.
 
         :param route: The route to add.
         :type route: Route
@@ -734,7 +734,7 @@ class BaseRouter(BaseModel):
         else:
             logger.warning(
                 "Local and remote route layers were not aligned. Remote hash "
-                "not updated. Use `RouteLayer.get_utterance_diff()` to see "
+                "not updated. Use `SemanticRouter.get_utterance_diff()` to see "
                 "details."
             )
 
@@ -752,7 +752,7 @@ class BaseRouter(BaseModel):
         threshold or utterances parameters, those fields are not updated.
         If neither field is provided raises a ValueError.
 
-        The name must exist within the local RouteLayer, if not a
+        The name must exist within the local SemanticRouter, if not a
         KeyError will be raised.
         """
         current_local_hash = self._get_hash()
diff --git a/semantic_router/routers/semantic.py b/semantic_router/routers/semantic.py
index 951ef6f76f0c17b502844716ae967acd019c753c..45493e67079369ea6017fa68905491f16248d62d 100644
--- a/semantic_router/routers/semantic.py
+++ b/semantic_router/routers/semantic.py
@@ -52,7 +52,7 @@ def is_valid(layer_config: str) -> bool:
         return False
 
 
-class RouteLayer(BaseRouter):
+class SemanticRouter(BaseRouter):
     index: BaseIndex = Field(default_factory=LocalIndex)
 
     @validator("index", pre=True, always=True)
@@ -312,9 +312,9 @@ class RouteLayer(BaseRouter):
         self._write_hash()
 
     def _local_upsert(self, utterances: List[Utterance]):
-        """Adds new routes to the RouteLayer.
+        """Adds new routes to the SemanticRouter.
 
-        :param utterances: The utterances to add to the local RouteLayer.
+        :param utterances: The utterances to add to the local SemanticRouter.
         :type utterances: List[Utterance]
         """
         new_routes = {route.name: route for route in self.routes}
@@ -336,9 +336,9 @@ class RouteLayer(BaseRouter):
         self.routes = list(new_routes.values())
 
     def _local_delete(self, utterances: List[Utterance]):
-        """Deletes routes from the local RouteLayer.
+        """Deletes routes from the local SemanticRouter.
 
-        :param utterances: The utterances to delete from the local RouteLayer.
+        :param utterances: The utterances to delete from the local SemanticRouter.
         :type utterances: List[Utterance]
         """
         # create dictionary of route names to utterances
@@ -427,7 +427,7 @@ class RouteLayer(BaseRouter):
 
     def __str__(self):
         return (
-            f"RouteLayer(encoder={self.encoder}, "
+            f"SemanticRouter(encoder={self.encoder}, "
             f"score_threshold={self.score_threshold}, "
             f"routes={self.routes})"
         )
@@ -450,7 +450,7 @@ class RouteLayer(BaseRouter):
         return cls(encoder=encoder, routes=config.routes, index=index)
 
     def add(self, route: Route):
-        """Add a route to the local RouteLayer and index.
+        """Add a route to the local SemanticRouter and index.
 
         :param route: The route to add.
         :type route: Route
@@ -480,7 +480,7 @@ class RouteLayer(BaseRouter):
         else:
             logger.warning(
                 "Local and remote route layers were not aligned. Remote hash "
-                "not updated. Use `RouteLayer.get_utterance_diff()` to see "
+                "not updated. Use `SemanticRouter.get_utterance_diff()` to see "
                 "details."
             )
 
@@ -498,7 +498,7 @@ class RouteLayer(BaseRouter):
         threshold or utterances parameters, those fields are not updated.
         If neither field is provided raises a ValueError.
 
-        The name must exist within the local RouteLayer, if not a
+        The name must exist within the local SemanticRouter, if not a
         KeyError will be raised.
         """
         current_local_hash = self._get_hash()
@@ -532,7 +532,7 @@ class RouteLayer(BaseRouter):
         else:
             logger.warning(
                 "Local and remote route layers were not aligned. Remote hash "
-                "not updated. Use `RouteLayer.get_utterance_diff()` to see "
+                "not updated. Use `SemanticRouter.get_utterance_diff()` to see "
                 "details."
             )
 
@@ -549,7 +549,7 @@ class RouteLayer(BaseRouter):
             current_remote_hash = current_local_hash
 
         if route_name not in [route.name for route in self.routes]:
-            err_msg = f"Route `{route_name}` not found in RouteLayer"
+            err_msg = f"Route `{route_name}` not found in SemanticRouter"
             logger.warning(err_msg)
             try:
                 self.index.delete(route_name=route_name)
@@ -564,7 +564,7 @@ class RouteLayer(BaseRouter):
         else:
             logger.warning(
                 "Local and remote route layers were not aligned. Remote hash "
-                "not updated. Use `RouteLayer.get_utterance_diff()` to see "
+                "not updated. Use `SemanticRouter.get_utterance_diff()` to see "
                 "details."
             )
 
@@ -618,7 +618,7 @@ class RouteLayer(BaseRouter):
         else:
             logger.warning(
                 "Local and remote route layers were not aligned. Remote hash "
-                "not updated. Use `RouteLayer.get_utterance_diff()` to see "
+                "not updated. Use `SemanticRouter.get_utterance_diff()` to see "
                 "details."
             )
 
@@ -959,7 +959,7 @@ class RouteLayer(BaseRouter):
 
 
 def threshold_random_search(
-    route_layer: RouteLayer,
+    route_layer: SemanticRouter,
     search_range: Union[int, float],
 ) -> Dict[str, float]:
     """Performs a random search iteration given a route layer and a search range."""
diff --git a/tests/unit/test_router.py b/tests/unit/test_router.py
index 61731b29a88c042bf031c8a43c5885e52724c0c4..2eef4666559db631cce399af990a40b067d0ea3d 100644
--- a/tests/unit/test_router.py
+++ b/tests/unit/test_router.py
@@ -10,7 +10,7 @@ from semantic_router.encoders import BaseEncoder, CohereEncoder, OpenAIEncoder
 from semantic_router.index.local import LocalIndex
 from semantic_router.index.pinecone import PineconeIndex
 from semantic_router.index.qdrant import QdrantIndex
-from semantic_router.routers import RouterConfig, RouteLayer
+from semantic_router.routers import RouterConfig, SemanticRouter
 from semantic_router.llms.base import BaseLLM
 from semantic_router.route import Route
 from platform import python_version
@@ -205,7 +205,7 @@ def get_test_encoders():
 class TestIndexEncoders:
     def test_initialization(self, routes, openai_encoder, index_cls, encoder_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=encoder_cls(),
             routes=routes,
             index=index,
@@ -228,22 +228,22 @@ class TestIndexEncoders:
     def test_initialization_different_encoders(self, encoder_cls, index_cls):
         index = init_index(index_cls)
         encoder = encoder_cls()
-        route_layer = RouteLayer(encoder=encoder, index=index)
+        route_layer = SemanticRouter(encoder=encoder, index=index)
         assert route_layer.score_threshold == encoder.score_threshold
 
     def test_initialization_no_encoder(self, openai_encoder, index_cls, encoder_cls):
         os.environ["OPENAI_API_KEY"] = "test_api_key"
-        route_layer_none = RouteLayer(encoder=None)
+        route_layer_none = SemanticRouter(encoder=None)
         assert route_layer_none.score_threshold == openai_encoder.score_threshold
 
 
 @pytest.mark.parametrize("index_cls", get_test_indexes())
-class TestRouteLayer:
+class TestSemanticRouter:
     def test_initialization_dynamic_route(
         self, dynamic_routes, openai_encoder, index_cls
     ):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=dynamic_routes,
             index=index,
@@ -254,7 +254,7 @@ class TestRouteLayer:
     def test_delete_index(self, openai_encoder, routes, index_cls):
         # TODO merge .delete_index() and .delete_all() and get working
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -269,7 +269,7 @@ class TestRouteLayer:
 
     def test_add_route(self, routes, openai_encoder, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder, routes=[], index=index, auto_sync="local"
         )
         if index_cls is PineconeIndex:
@@ -297,7 +297,7 @@ class TestRouteLayer:
 
     def test_list_route_names(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -312,7 +312,7 @@ class TestRouteLayer:
 
     def test_delete_route(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -337,7 +337,7 @@ class TestRouteLayer:
 
     def test_remove_route_not_found(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         if index_cls is PineconeIndex:
             time.sleep(PINECONE_SLEEP)
         # Attempt to remove a route that does not exist
@@ -347,7 +347,7 @@ class TestRouteLayer:
 
     def test_add_multiple_routes(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             index=index,
             auto_sync="local",
@@ -362,7 +362,7 @@ class TestRouteLayer:
 
     def test_query_and_classification(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls, dimensions=3)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -375,7 +375,7 @@ class TestRouteLayer:
 
     def test_query_filter(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls, dimensions=3)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -398,7 +398,7 @@ class TestRouteLayer:
     def test_query_filter_pinecone(self, openai_encoder, routes, index_cls):
         if index_cls is PineconeIndex:
             pineconeindex = init_index(index_cls, dimensions=3)
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=pineconeindex,
@@ -420,7 +420,7 @@ class TestRouteLayer:
     def test_namespace_pinecone_index(self, openai_encoder, routes, index_cls):
         if index_cls is PineconeIndex:
             pineconeindex = init_index(index_cls, namespace="test")
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=pineconeindex,
@@ -438,13 +438,13 @@ class TestRouteLayer:
             route_layer.index.index.delete(namespace="test", delete_all=True)
 
     def test_query_with_no_index(self, openai_encoder, index_cls):
-        route_layer = RouteLayer(encoder=openai_encoder)
+        route_layer = SemanticRouter(encoder=openai_encoder)
         with pytest.raises(ValueError):
             assert route_layer(text="Anything").name is None
 
     def test_query_with_vector(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -458,13 +458,13 @@ class TestRouteLayer:
 
     def test_query_with_no_text_or_vector(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         with pytest.raises(ValueError):
             route_layer()
 
     def test_semantic_classify(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -483,7 +483,7 @@ class TestRouteLayer:
 
     def test_semantic_classify_multiple_routes(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -505,7 +505,7 @@ class TestRouteLayer:
         self, openai_encoder, dynamic_routes, index_cls
     ):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder, routes=dynamic_routes, index=index
         )
         vector = [0.1, 0.2, 0.3]
@@ -514,7 +514,7 @@ class TestRouteLayer:
 
     def test_pass_threshold(self, openai_encoder, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             index=index,
             auto_sync="local",
@@ -524,7 +524,7 @@ class TestRouteLayer:
 
     def test_failover_score_threshold(self, openai_encoder, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             index=index,
             auto_sync="local",
@@ -538,7 +538,7 @@ class TestRouteLayer:
             temp.close()  # Close the file to ensure it can be opened again on Windows
             os.environ["OPENAI_API_KEY"] = "test_api_key"
             index = init_index(index_cls)
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=index,
@@ -546,7 +546,7 @@ class TestRouteLayer:
             )
             route_layer.to_json(temp_path)
             assert os.path.exists(temp_path)
-            route_layer_from_file = RouteLayer.from_json(temp_path)
+            route_layer_from_file = SemanticRouter.from_json(temp_path)
             if index_cls is PineconeIndex:
                 time.sleep(PINECONE_SLEEP)  # allow for index to be populated
             assert (
@@ -563,7 +563,7 @@ class TestRouteLayer:
             temp.close()  # Close the file to ensure it can be opened again on Windows
             os.environ["OPENAI_API_KEY"] = "test_api_key"
             index = init_index(index_cls)
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=index,
@@ -571,7 +571,7 @@ class TestRouteLayer:
             )
             route_layer.to_yaml(temp_path)
             assert os.path.exists(temp_path)
-            route_layer_from_file = RouteLayer.from_yaml(temp_path)
+            route_layer_from_file = SemanticRouter.from_yaml(temp_path)
             if index_cls is PineconeIndex:
                 time.sleep(PINECONE_SLEEP)  # allow for index to be populated
             assert (
@@ -690,12 +690,12 @@ class TestRouteLayer:
     def test_config(self, openai_encoder, routes, index_cls):
         os.environ["OPENAI_API_KEY"] = "test_api_key"
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         # confirm route creation functions as expected
         layer_config = route_layer.to_config()
         assert layer_config.routes == route_layer.routes
         # now load from config and confirm it's the same
-        route_layer_from_config = RouteLayer.from_config(layer_config, index)
+        route_layer_from_config = SemanticRouter.from_config(layer_config, index)
         if index_cls is PineconeIndex:
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
         assert (
@@ -705,14 +705,14 @@ class TestRouteLayer:
 
     def test_get_thresholds(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         assert route_layer.get_thresholds() == {"Route 1": 0.3, "Route 2": 0.3}
 
     def test_with_multiple_routes_passing_threshold(
         self, openai_encoder, routes, index_cls
     ):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         route_layer.score_threshold = 0.5  # Set the score_threshold if needed
         # Assuming route_layer is already set up with routes "Route 1" and "Route 2"
         query_results = [
@@ -730,7 +730,7 @@ class TestRouteLayer:
 
     def test_with_no_routes_passing_threshold(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         route_layer.score_threshold = 0.5
         # Override _pass_threshold to always return False for this test
         route_layer._pass_threshold = lambda scores, threshold: False
@@ -746,7 +746,7 @@ class TestRouteLayer:
 
     def test_with_no_query_results(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         route_layer.score_threshold = 0.5
         query_results = []
         expected = []
@@ -757,7 +757,7 @@ class TestRouteLayer:
 
     def test_with_unrecognized_route(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         route_layer.score_threshold = 0.5
         # Test with a route name that does not exist in the route_layer's routes
         query_results = [{"route": "UnrecognizedRoute", "score": 0.9}]
@@ -767,7 +767,7 @@ class TestRouteLayer:
 
     def test_retrieve_with_text(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -782,7 +782,7 @@ class TestRouteLayer:
 
     def test_retrieve_with_vector(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -797,7 +797,7 @@ class TestRouteLayer:
 
     def test_retrieve_without_text_or_vector(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -808,7 +808,7 @@ class TestRouteLayer:
 
     def test_retrieve_no_matches(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             index=index,
@@ -820,7 +820,7 @@ class TestRouteLayer:
 
     def test_retrieve_one_match(self, openai_encoder, routes_3, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes_3,
             index=index,
@@ -838,7 +838,7 @@ class TestRouteLayer:
         self, openai_encoder, routes_2, index_cls
     ):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes_2,
             index=index,
@@ -857,7 +857,7 @@ class TestRouteLayer:
         self, openai_encoder, routes, index_cls
     ):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         unsupported_aggregation = "unsupported_aggregation_method"
         with pytest.raises(
             ValueError,
@@ -867,7 +867,7 @@ class TestRouteLayer:
 
     def test_refresh_routes_not_implemented(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         with pytest.raises(
             NotImplementedError, match="This method has not yet been implemented."
         ):
@@ -875,7 +875,7 @@ class TestRouteLayer:
 
     def test_update_threshold(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         route_name = "Route 1"
         new_threshold = 0.8
         route_layer.update(name=route_name, threshold=new_threshold)
@@ -886,7 +886,7 @@ class TestRouteLayer:
 
     def test_update_non_existent_route(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         non_existent_route = "Non-existent Route"
         with pytest.raises(
             ValueError,
@@ -896,7 +896,7 @@ class TestRouteLayer:
 
     def test_update_without_parameters(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         with pytest.raises(
             ValueError,
             match="At least one of 'threshold' or 'utterances' must be provided.",
@@ -905,7 +905,7 @@ class TestRouteLayer:
 
     def test_update_utterances_not_implemented(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes, index=index)
         with pytest.raises(
             NotImplementedError,
             match="The update method cannot be used for updating utterances yet.",
@@ -915,7 +915,7 @@ class TestRouteLayer:
 
 class TestLayerFit:
     def test_eval(self, openai_encoder, routes, test_data):
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             auto_sync="local",
@@ -926,7 +926,7 @@ class TestLayerFit:
         route_layer.evaluate(X=X, y=y, batch_size=int(len(test_data) / 5))
 
     def test_fit(self, openai_encoder, routes, test_data):
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             auto_sync="local",
@@ -1019,7 +1019,7 @@ class TestRouterConfig:
 
     def test_setting_aggregation_methods(self, openai_encoder, routes):
         for agg in ["sum", "mean", "max"]:
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 aggregation=agg,
@@ -1041,7 +1041,7 @@ class TestRouterConfig:
             {"route": "Route 3", "score": 1.0},
         ]
         for agg in ["sum", "mean", "max"]:
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 aggregation=agg,
diff --git a/tests/unit/test_sync.py b/tests/unit/test_sync.py
index f38635c2a164b90698877105c8882bb5e17723a4..2327fc0642b7acfe41103c366376840fa662dd06 100644
--- a/tests/unit/test_sync.py
+++ b/tests/unit/test_sync.py
@@ -7,7 +7,7 @@ from typing import Optional
 from semantic_router.encoders import BaseEncoder, CohereEncoder, OpenAIEncoder
 from semantic_router.index.pinecone import PineconeIndex
 from semantic_router.schema import Utterance
-from semantic_router.routers.base import RouteLayer
+from semantic_router.routers.base import SemanticRouter
 from semantic_router.route import Route
 from platform import python_version
 
@@ -187,13 +187,13 @@ def get_test_indexes():
 
 
 @pytest.mark.parametrize("index_cls", get_test_indexes())
-class TestRouteLayer:
+class TestSemanticRouter:
     @pytest.mark.skipif(
         os.environ.get("PINECONE_API_KEY") is None, reason="Pinecone API key required"
     )
     def test_initialization(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        _ = RouteLayer(
+        _ = SemanticRouter(
             encoder=openai_encoder,
             routes=routes,
             top_k=10,
@@ -206,7 +206,7 @@ class TestRouteLayer:
     )
     def test_second_initialization_sync(self, openai_encoder, routes, index_cls):
         index = init_index(index_cls)
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder, routes=routes, index=index, auto_sync="local"
         )
         if index_cls is PineconeIndex:
@@ -220,10 +220,10 @@ class TestRouteLayer:
         self, openai_encoder, routes, routes_2, index_cls
     ):
         index = init_index(index_cls)
-        _ = RouteLayer(
+        _ = SemanticRouter(
             encoder=openai_encoder, routes=routes, index=index, auto_sync="local"
         )
-        route_layer = RouteLayer(encoder=openai_encoder, routes=routes_2, index=index)
+        route_layer = SemanticRouter(encoder=openai_encoder, routes=routes_2, index=index)
         if index_cls is PineconeIndex:
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
         assert route_layer.is_synced() is False
@@ -233,10 +233,10 @@ class TestRouteLayer:
     )
     def test_utterance_diff(self, openai_encoder, routes, routes_2, index_cls):
         index = init_index(index_cls)
-        _ = RouteLayer(
+        _ = SemanticRouter(
             encoder=openai_encoder, routes=routes, index=index, auto_sync="local"
         )
-        route_layer_2 = RouteLayer(encoder=openai_encoder, routes=routes_2, index=index)
+        route_layer_2 = SemanticRouter(encoder=openai_encoder, routes=routes_2, index=index)
         if index_cls is PineconeIndex:
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
         diff = route_layer_2.get_utterance_diff(include_metadata=True)
@@ -256,13 +256,13 @@ class TestRouteLayer:
         if index_cls is PineconeIndex:
             # TEST LOCAL
             pinecone_index = init_index(index_cls)
-            _ = RouteLayer(
+            _ = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=pinecone_index,
             )
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes_2,
                 index=pinecone_index,
@@ -281,14 +281,14 @@ class TestRouteLayer:
         if index_cls is PineconeIndex:
             # TEST REMOTE
             pinecone_index = init_index(index_cls)
-            _ = RouteLayer(
+            _ = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes_2,
                 index=pinecone_index,
                 auto_sync="local",
             )
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=pinecone_index,
@@ -309,14 +309,14 @@ class TestRouteLayer:
         if index_cls is PineconeIndex:
             # TEST MERGE FORCE LOCAL
             pinecone_index = init_index(index_cls)
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=pinecone_index,
                 auto_sync="local",
             )
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes_2,
                 index=pinecone_index,
@@ -347,14 +347,14 @@ class TestRouteLayer:
         if index_cls is PineconeIndex:
             # TEST MERGE FORCE LOCAL
             pinecone_index = init_index(index_cls)
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=pinecone_index,
                 auto_sync="local",
             )
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes_2,
                 index=pinecone_index,
@@ -385,7 +385,7 @@ class TestRouteLayer:
         os.environ.get("PINECONE_API_KEY") is None, reason="Pinecone API key required"
     )
     def test_sync(self, openai_encoder, index_cls):
-        route_layer = RouteLayer(
+        route_layer = SemanticRouter(
             encoder=openai_encoder,
             routes=[],
             index=init_index(index_cls),
@@ -403,14 +403,14 @@ class TestRouteLayer:
         if index_cls is PineconeIndex:
             # TEST MERGE
             pinecone_index = init_index(index_cls)
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes_2,
                 index=pinecone_index,
                 auto_sync="local",
             )
             time.sleep(PINECONE_SLEEP)  # allow for index to be populated
-            route_layer = RouteLayer(
+            route_layer = SemanticRouter(
                 encoder=openai_encoder,
                 routes=routes,
                 index=pinecone_index,